From 17dcab0edd720be44e8d1bd2be4b34e1405bc17f Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 13:29:24 -0700 Subject: [PATCH 001/123] chore(modules): bump minimum CMake version for modules support --- CMakeLists.txt | 8 +------- cmake/CMakeLists.txt | 2 +- samples/CMakeLists.txt | 2 +- samples/client/CMakeLists.txt | 2 +- samples/client/benchmark/CMakeLists.txt | 2 +- samples/client/multiple/CMakeLists.txt | 2 +- samples/client/mutate/CMakeLists.txt | 2 +- samples/client/nestedinput/CMakeLists.txt | 2 +- samples/client/query/CMakeLists.txt | 2 +- samples/client/subscribe/CMakeLists.txt | 2 +- samples/learn/CMakeLists.txt | 2 +- samples/learn/schema/CMakeLists.txt | 2 +- samples/proxy/CMakeLists.txt | 2 +- samples/proxy/query/CMakeLists.txt | 2 +- samples/proxy/schema/CMakeLists.txt | 2 +- samples/today/CMakeLists.txt | 2 +- samples/today/nointrospection/CMakeLists.txt | 2 +- samples/today/schema/CMakeLists.txt | 2 +- samples/validation/CMakeLists.txt | 2 +- samples/validation/schema/CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- src/introspection/CMakeLists.txt | 2 +- test/CMakeLists.txt | 2 +- 23 files changed, 23 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f25e927..8acdcdde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) - -# Enable CMAKE_MSVC_RUNTIME_LIBRARY on Windows: https://cmake.org/cmake/help/latest/policy/CMP0091.html -cmake_policy(SET CMP0091 NEW) - -# Do not set default MSVC warning flags: https://cmake.org/cmake/help/latest/policy/CMP0092.html -cmake_policy(SET CMP0092 NEW) +cmake_minimum_required(VERSION 3.28) # Export compile commands for other tools, e.g. SonarLint. set(CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 1db60cea..1fdaf4a5 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Enable version checks in find_package include(CMakePackageConfigHelpers) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index bddfd792..74452ba8 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) add_subdirectory(client) add_subdirectory(learn) diff --git a/samples/client/CMakeLists.txt b/samples/client/CMakeLists.txt index 71ff74de..b5eb0d8a 100644 --- a/samples/client/CMakeLists.txt +++ b/samples/client/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) add_subdirectory(query) add_subdirectory(mutate) diff --git a/samples/client/benchmark/CMakeLists.txt b/samples/client/benchmark/CMakeLists.txt index ea0ab74c..c2ec979e 100644 --- a/samples/client/benchmark/CMakeLists.txt +++ b/samples/client/benchmark/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/client/multiple/CMakeLists.txt b/samples/client/multiple/CMakeLists.txt index d011f933..9f72d51d 100644 --- a/samples/client/multiple/CMakeLists.txt +++ b/samples/client/multiple/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/client/mutate/CMakeLists.txt b/samples/client/mutate/CMakeLists.txt index 61b3ab67..bdf63420 100644 --- a/samples/client/mutate/CMakeLists.txt +++ b/samples/client/mutate/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/client/nestedinput/CMakeLists.txt b/samples/client/nestedinput/CMakeLists.txt index b9714ed2..470a7c71 100644 --- a/samples/client/nestedinput/CMakeLists.txt +++ b/samples/client/nestedinput/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/client/query/CMakeLists.txt b/samples/client/query/CMakeLists.txt index dd483b6c..6fbcfcc1 100644 --- a/samples/client/query/CMakeLists.txt +++ b/samples/client/query/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/client/subscribe/CMakeLists.txt b/samples/client/subscribe/CMakeLists.txt index fb3ea5eb..6d937548 100644 --- a/samples/client/subscribe/CMakeLists.txt +++ b/samples/client/subscribe/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/learn/CMakeLists.txt b/samples/learn/CMakeLists.txt index 3be7bcf0..7c0db253 100644 --- a/samples/learn/CMakeLists.txt +++ b/samples/learn/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) add_subdirectory(schema) add_library(star_wars STATIC diff --git a/samples/learn/schema/CMakeLists.txt b/samples/learn/schema/CMakeLists.txt index 2cab0cc0..589e3b6a 100644 --- a/samples/learn/schema/CMakeLists.txt +++ b/samples/learn/schema/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/proxy/CMakeLists.txt b/samples/proxy/CMakeLists.txt index df821c20..e518aca8 100644 --- a/samples/proxy/CMakeLists.txt +++ b/samples/proxy/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) add_subdirectory(query) add_subdirectory(schema) diff --git a/samples/proxy/query/CMakeLists.txt b/samples/proxy/query/CMakeLists.txt index f774c8f8..4c8e5e50 100644 --- a/samples/proxy/query/CMakeLists.txt +++ b/samples/proxy/query/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/proxy/schema/CMakeLists.txt b/samples/proxy/schema/CMakeLists.txt index 03912cd3..bb9a16a1 100644 --- a/samples/proxy/schema/CMakeLists.txt +++ b/samples/proxy/schema/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/today/CMakeLists.txt b/samples/today/CMakeLists.txt index 7c9eaa33..c3b9b2bb 100644 --- a/samples/today/CMakeLists.txt +++ b/samples/today/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # todaygraphql add_subdirectory(schema) diff --git a/samples/today/nointrospection/CMakeLists.txt b/samples/today/nointrospection/CMakeLists.txt index 5bea126a..5f98c0c0 100644 --- a/samples/today/nointrospection/CMakeLists.txt +++ b/samples/today/nointrospection/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/today/schema/CMakeLists.txt b/samples/today/schema/CMakeLists.txt index 0c6403ec..e7e7ee23 100644 --- a/samples/today/schema/CMakeLists.txt +++ b/samples/today/schema/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/samples/validation/CMakeLists.txt b/samples/validation/CMakeLists.txt index 8db4b408..5968f24b 100644 --- a/samples/validation/CMakeLists.txt +++ b/samples/validation/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) if(GRAPHQL_BUILD_TESTS) add_subdirectory(schema) diff --git a/samples/validation/schema/CMakeLists.txt b/samples/validation/schema/CMakeLists.txt index 106fad47..4d680f6c 100644 --- a/samples/validation/schema/CMakeLists.txt +++ b/samples/validation/schema/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2d763474..6bab8b34 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) if(GRAPHQL_UPDATE_VERSION) # internal/Version.h diff --git a/src/introspection/CMakeLists.txt b/src/introspection/CMakeLists.txt index 82b8203d..329b95a7 100644 --- a/src/introspection/CMakeLists.txt +++ b/src/introspection/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) # Normally this would be handled by find_package(cppgraphqlgen CONFIG). include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/cppgraphqlgen-functions.cmake) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a3b0d52f..9e0a8150 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.28) find_package(GTest MODULE REQUIRED) From b152a94540371ad929bc739ae5d58dd82234ae9a Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 13:32:48 -0700 Subject: [PATCH 002/123] chore(modules): make macOS build action use Ninja instead of makefiles --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 16b94358..d594d04c 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -40,7 +40,7 @@ jobs: $cacheAccess = $(if ('${{ steps.cache-vcpkg.outputs.cache-hit }}' -eq 'true') { 'read' } else { 'write' }) $env:VCPKG_BINARY_SOURCES = "clear;files,$cachedBinaries,$cacheAccess" - cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" ${{ github.workspace }} + cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" -G Ninja ${{ github.workspace }} - name: Build working-directory: build/ From cc886944c378353dd72ec98b29bdbb77b1c6cfaa Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 14:18:58 -0700 Subject: [PATCH 003/123] chore(modules): add vcpkg submodule and update workflows --- .github/workflows/linux.yml | 6 +++--- .github/workflows/macos.yml | 10 ++++++++-- .github/workflows/windows.yml | 7 ++++++- .gitmodules | 3 +++ vcpkg | 1 + 5 files changed, 21 insertions(+), 6 deletions(-) create mode 160000 vcpkg diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 486542c4..95d32441 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -19,7 +19,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get update - sudo apt-get install -yq libgtest-dev libboost-program-options-dev rapidjson-dev ninja-build gcc-10 g++-10 + sudo apt-get install -yq libgtest-dev libboost-program-options-dev rapidjson-dev ninja-build gcc-14 g++-14 - name: Build GTest run: | @@ -35,8 +35,8 @@ jobs: - name: Configure CMake shell: pwsh env: - CC: gcc-10 - CXX: g++-10 + CC: gcc-14 + CXX: g++-14 working-directory: build/ run: | $cmakeBuildType = '${{ matrix.config }}' diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index d594d04c..53287e39 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -9,12 +9,13 @@ jobs: matrix: config: [Debug, Release] - runs-on: macos-13 + runs-on: macos-latest steps: - uses: actions/checkout@v4.1.3 with: submodules: true + - uses: seanmiddleditch/gha-setup-ninja@96bed6edff20d1dd61ecff9b75cc519d516e6401 - name: Cache vcpkg uses: actions/cache@v4.0.2 @@ -31,9 +32,14 @@ jobs: - name: Configure shell: pwsh + env: + VCPKG_ROOT: ${{ github.workspace }}/vcpkg working-directory: build/ run: | - $vcpkgToolchain = Join-Path $env:VCPKG_INSTALLATION_ROOT './scripts/buildsystems/vcpkg.cmake' -Resolve + & "${env:VCPKG_ROOT}/bootstrap-vcpkg.sh" + & "${env:VCPKG_ROOT}/vcpkg integrate install" + + $vcpkgToolchain = Join-Path $env:VCPKG_ROOT './scripts/buildsystems/vcpkg.cmake' -Resolve $cmakeBuildType = '${{ matrix.config }}' $cachedBinaries = Join-Path $(Get-Location) './vcpkg_cache/' -Resolve diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 3e3796bf..514eee21 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -38,9 +38,14 @@ jobs: - name: Configure shell: pwsh + env: + VCPKG_ROOT: ${{ github.workspace }}\vcpkg working-directory: build/ run: | - $vcpkgToolchain = Join-Path $env:VCPKG_INSTALLATION_ROOT '.\scripts\buildsystems\vcpkg.cmake' -Resolve + & "${env:VCPKG_ROOT}/bootstrap-vcpkg.bat" + & "${env:VCPKG_ROOT}/vcpkg" integrate install + + $vcpkgToolchain = Join-Path $env:VCPKG_ROOT './scripts/buildsystems/vcpkg.cmake' -Resolve $vcpkgTriplet = '${{ steps.set-variables.outputs.vcpkg_triplet }}' $cmakeSharedLibs = $(if ('${{ matrix.libs }}' -eq 'shared') { 'ON' } else { 'OFF' }) $msbuildArch = $(if ('${{ matrix.arch }}' -eq 'x64') { 'X64' } else { 'Win32' }) diff --git a/.gitmodules b/.gitmodules index 63c116a4..425cae62 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "PEGTL"] path = PEGTL url = https://github.com/taocpp/PEGTL.git +[submodule "vcpkg"] + path = vcpkg + url = https://github.com/microsoft/vcpkg.git diff --git a/vcpkg b/vcpkg new file mode 160000 index 00000000..49e1e8f7 --- /dev/null +++ b/vcpkg @@ -0,0 +1 @@ +Subproject commit 49e1e8f77565d452569f39e538b90cb9768e8b11 From 10391bb0ccb76dc2bdf635359271eb2a91f8e2d8 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 14:38:37 -0700 Subject: [PATCH 004/123] chore(modules): workflow fixes --- .github/workflows/linux.yml | 3 +++ .github/workflows/macos.yml | 11 ++++++++--- .github/workflows/windows.yml | 11 ++++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 95d32441..0aad7cf5 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -18,6 +18,9 @@ jobs: - name: Install Dependencies run: | + sudo apt-get update + sudo apt-get upgrade + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install -yq libgtest-dev libboost-program-options-dev rapidjson-dev ninja-build gcc-14 g++-14 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 53287e39..9a475956 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -30,15 +30,20 @@ jobs: cmake -E make_directory build cmake -E make_directory build/vcpkg_cache + - name: Boostrap vcpkg + shell: pwsh + working-directory: vcpkg/ + run: | + ./bootstrap-vcpkg.sh + ./vcpkg integrate install + git fetch + - name: Configure shell: pwsh env: VCPKG_ROOT: ${{ github.workspace }}/vcpkg working-directory: build/ run: | - & "${env:VCPKG_ROOT}/bootstrap-vcpkg.sh" - & "${env:VCPKG_ROOT}/vcpkg integrate install" - $vcpkgToolchain = Join-Path $env:VCPKG_ROOT './scripts/buildsystems/vcpkg.cmake' -Resolve $cmakeBuildType = '${{ matrix.config }}' diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 514eee21..fe3f3c07 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -36,15 +36,20 @@ jobs: cmake -E make_directory build cmake -E make_directory build/vcpkg_cache + - name: Boostrap vcpkg + shell: pwsh + working-directory: vcpkg/ + run: | + ./bootstrap-vcpkg.bat + ./vcpkg integrate install + git fetch + - name: Configure shell: pwsh env: VCPKG_ROOT: ${{ github.workspace }}\vcpkg working-directory: build/ run: | - & "${env:VCPKG_ROOT}/bootstrap-vcpkg.bat" - & "${env:VCPKG_ROOT}/vcpkg" integrate install - $vcpkgToolchain = Join-Path $env:VCPKG_ROOT './scripts/buildsystems/vcpkg.cmake' -Resolve $vcpkgTriplet = '${{ steps.set-variables.outputs.vcpkg_triplet }}' $cmakeSharedLibs = $(if ('${{ matrix.libs }}' -eq 'shared') { 'ON' } else { 'OFF' }) From 8aad12301191d22454a0d6dcaeb04d315ff89ae1 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 14:45:25 -0700 Subject: [PATCH 005/123] chore(modules): rewind vcpkg submodule to match baseline.json --- vcpkg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcpkg b/vcpkg index 49e1e8f7..7aeffc91 160000 --- a/vcpkg +++ b/vcpkg @@ -1 +1 @@ -Subproject commit 49e1e8f77565d452569f39e538b90cb9768e8b11 +Subproject commit 7aeffc91033ad35cc4e2c152f213a866ec6c11ac From 3a6166ab50e51ae79e686c37d8c1fe66ca5577bb Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 14:49:00 -0700 Subject: [PATCH 006/123] chore(modules): try universe PPA on ubuntu-latest --- .github/workflows/linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 0aad7cf5..60c6106c 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -20,7 +20,7 @@ jobs: run: | sudo apt-get update sudo apt-get upgrade - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + sudo add-apt-repository -y universe sudo apt-get update sudo apt-get install -yq libgtest-dev libboost-program-options-dev rapidjson-dev ninja-build gcc-14 g++-14 From ab729b2f2ae2c44bd15560f31fa672018753eac6 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 15:25:55 -0700 Subject: [PATCH 007/123] fix(workflow): try synchronizing the submodule with manifest baseline --- .github/workflows/linux.yml | 2 +- .github/workflows/macos.yml | 2 +- .github/workflows/windows.yml | 1 - vcpkg | 2 +- vcpkg.json | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 60c6106c..cec4eb71 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -9,7 +9,7 @@ jobs: matrix: config: [Debug, Release] - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4.1.3 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 9a475956..ecb6a990 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -36,7 +36,6 @@ jobs: run: | ./bootstrap-vcpkg.sh ./vcpkg integrate install - git fetch - name: Configure shell: pwsh @@ -51,6 +50,7 @@ jobs: $cacheAccess = $(if ('${{ steps.cache-vcpkg.outputs.cache-hit }}' -eq 'true') { 'read' } else { 'write' }) $env:VCPKG_BINARY_SOURCES = "clear;files,$cachedBinaries,$cacheAccess" + $env:PATH = "${env:PATH}:${{ github.workspace }}/ninja-build" cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" -G Ninja ${{ github.workspace }} - name: Build diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index fe3f3c07..fba67358 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -42,7 +42,6 @@ jobs: run: | ./bootstrap-vcpkg.bat ./vcpkg integrate install - git fetch - name: Configure shell: pwsh diff --git a/vcpkg b/vcpkg index 7aeffc91..b810d1cd 160000 --- a/vcpkg +++ b/vcpkg @@ -1 +1 @@ -Subproject commit 7aeffc91033ad35cc4e2c152f213a866ec6c11ac +Subproject commit b810d1cdd47bfe729a5c78aa1e5b16dfa30da873 diff --git a/vcpkg.json b/vcpkg.json index 7c62b562..273930f9 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -49,5 +49,5 @@ "dependencies": [ "pegtl" ], - "builtin-baseline": "7aeffc91033ad35cc4e2c152f213a866ec6c11ac" + "builtin-baseline": "b810d1cdd47bfe729a5c78aa1e5b16dfa30da873" } From f54f04005ab3c8354b0214b56158d05aa3ed1c08 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 15:33:23 -0700 Subject: [PATCH 008/123] fix(workflow): try fetching all history in checkout --- .github/workflows/linux.yml | 2 +- .github/workflows/macos.yml | 2 ++ .github/workflows/windows.yml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index cec4eb71..58921f51 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -3,7 +3,7 @@ name: Linux on: [push, pull_request] jobs: - gcc10: + gcc14: strategy: fail-fast: false matrix: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index ecb6a990..7bf690db 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -15,6 +15,8 @@ jobs: - uses: actions/checkout@v4.1.3 with: submodules: true + fetch-depth: 0 + - uses: seanmiddleditch/gha-setup-ninja@96bed6edff20d1dd61ecff9b75cc519d516e6401 - name: Cache vcpkg diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index fba67358..c93570a0 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -17,6 +17,7 @@ jobs: - uses: actions/checkout@v4.1.3 with: submodules: true + fetch-depth: 0 - name: Set target triplet id: set-variables From 743fb91b482395ba5ecc59f7a4f02631df17c1ff Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 15:51:19 -0700 Subject: [PATCH 009/123] fix(workflow): hash vcpkg.json manifest in cache key --- .github/workflows/macos.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7bf690db..01eefd0d 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -24,7 +24,7 @@ jobs: id: cache-vcpkg with: path: build/vcpkg_cache/ - key: vcpkg-binaries-x64-osx + key: vcpkg-binaries-x64-osx-${{ hashFiles('vcpkg.json') }} - name: Create Build Environment if: ${{ !steps.cache-vcpkg.outputs.cache-hit }} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index c93570a0..cd638c24 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -29,7 +29,7 @@ jobs: id: cache-vcpkg with: path: build/vcpkg_cache/ - key: vcpkg-binaries-${{ steps.set-variables.outputs.vcpkg_triplet }} + key: vcpkg-binaries-${{ steps.set-variables.outputs.vcpkg_triplet }}-${{ hashFiles('vcpkg.json') }} - name: Create Build Environment if: ${{ !steps.cache-vcpkg.outputs.cache-hit }} From b045094bedc0b79efaae58611cee968cb9a6c302 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 15:54:56 -0700 Subject: [PATCH 010/123] fix(workflow): remove old arch from macos cache key --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 01eefd0d..70cea90b 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -24,7 +24,7 @@ jobs: id: cache-vcpkg with: path: build/vcpkg_cache/ - key: vcpkg-binaries-x64-osx-${{ hashFiles('vcpkg.json') }} + key: vcpkg-binaries-osx-${{ hashFiles('vcpkg.json') }} - name: Create Build Environment if: ${{ !steps.cache-vcpkg.outputs.cache-hit }} From 1c7773333da6e0d75595dac46436dd25f8e4c07a Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 16:23:49 -0700 Subject: [PATCH 011/123] fix(vcpkg): rollback submodule to match vcpkg distributed with VS --- vcpkg | 2 +- vcpkg.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vcpkg b/vcpkg index b810d1cd..7aeffc91 160000 --- a/vcpkg +++ b/vcpkg @@ -1 +1 @@ -Subproject commit b810d1cdd47bfe729a5c78aa1e5b16dfa30da873 +Subproject commit 7aeffc91033ad35cc4e2c152f213a866ec6c11ac diff --git a/vcpkg.json b/vcpkg.json index 273930f9..7c62b562 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -49,5 +49,5 @@ "dependencies": [ "pegtl" ], - "builtin-baseline": "b810d1cdd47bfe729a5c78aa1e5b16dfa30da873" + "builtin-baseline": "7aeffc91033ad35cc4e2c152f213a866ec6c11ac" } From c0831b7e1afbe977a10d85349e1bf718d4b2ef55 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 16:46:02 -0700 Subject: [PATCH 012/123] fix(cmake): opt-in to CMP0167 BoostConfig.cmake policy in 3.30 --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8acdcdde..4c6440dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,11 @@ cmake_minimum_required(VERSION 3.28) +if(POLICY CMP0167) + # Prefer the upstream BoostConfig.cmake file instead of the builtin FindBoost module: https://cmake.org/cmake/help/latest/policy/CMP0167.html + cmake_policy(SET CMP0167 NEW) +endif() + # Export compile commands for other tools, e.g. SonarLint. set(CMAKE_EXPORT_COMPILE_COMMANDS ON) From 8553608665001e6851e1ea4ddfddc13a2a1c95c5 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 10 Sep 2024 16:58:04 -0700 Subject: [PATCH 013/123] fix(cmake): use the right variable exported from BoostConfig.cmake --- samples/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 74452ba8..99131474 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -15,7 +15,7 @@ if(GRAPHQL_BUILD_HTTP_SAMPLE) try_compile(TEST_RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/test_boost_beast.cpp - CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${Boost_INCLUDE_DIR} + CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${Boost_INCLUDE_DIRS} CXX_STANDARD 20) if(TEST_RESULT) From 8f7aabb9a532359cf3dfe059676e4e7521fd0ffc Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 14:29:53 -0700 Subject: [PATCH 014/123] fix(includes): get rid of dependencies from internal headers on public headers --- include/graphqlservice/GraphQLClient.h | 19 ++----- include/graphqlservice/GraphQLParse.h | 12 +---- include/graphqlservice/GraphQLResponse.h | 15 +----- include/graphqlservice/GraphQLService.h | 25 +++------- include/graphqlservice/JSONResponse.h | 16 ++---- include/graphqlservice/internal/Base64.h | 12 +---- include/graphqlservice/internal/DllExports.h | 49 +++++++++++++++++++ include/graphqlservice/internal/Grammar.h | 2 +- .../graphqlservice/internal/Introspection.h | 3 +- include/graphqlservice/internal/Schema.h | 5 +- include/graphqlservice/internal/SyntaxTree.h | 2 +- .../introspection/IntrospectionSchema.h | 3 ++ samples/learn/schema/StarWarsSchema.h | 3 ++ samples/proxy/schema/ProxySchema.h | 3 ++ samples/today/nointrospection/TodaySchema.h | 3 ++ samples/today/schema/TodaySchema.h | 3 ++ samples/validation/schema/ValidationSchema.h | 3 ++ src/SchemaGenerator.cpp | 5 +- src/introspection/IntrospectionSchema.h | 3 ++ 19 files changed, 100 insertions(+), 86 deletions(-) create mode 100644 include/graphqlservice/internal/DllExports.h diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index 1321c1b4..2aa7835d 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -6,21 +6,10 @@ #ifndef GRAPHQLCLIENT_H #define GRAPHQLCLIENT_H -// clang-format off -#ifdef GRAPHQL_DLLEXPORTS - #ifdef IMPL_GRAPHQLCLIENT_DLL - #define GRAPHQLCLIENT_EXPORT __declspec(dllexport) - #else // !IMPL_GRAPHQLCLIENT_DLL - #define GRAPHQLCLIENT_EXPORT __declspec(dllimport) - #endif // !IMPL_GRAPHQLCLIENT_DLL -#else // !GRAPHQL_DLLEXPORTS - #define GRAPHQLCLIENT_EXPORT -#endif // !GRAPHQL_DLLEXPORTS -// clang-format on - -#include "graphqlservice/GraphQLResponse.h" - -#include "graphqlservice/internal/Version.h" +#include "GraphQLResponse.h" + +#include "internal/Version.h" +#include "internal/DllExports.h" #include #include diff --git a/include/graphqlservice/GraphQLParse.h b/include/graphqlservice/GraphQLParse.h index e983b224..cfd8682f 100644 --- a/include/graphqlservice/GraphQLParse.h +++ b/include/graphqlservice/GraphQLParse.h @@ -6,17 +6,7 @@ #ifndef GRAPHQLPARSE_H #define GRAPHQLPARSE_H -// clang-format off -#ifdef GRAPHQL_DLLEXPORTS - #ifdef IMPL_GRAPHQLPEG_DLL - #define GRAPHQLPEG_EXPORT __declspec(dllexport) - #else // !IMPL_GRAPHQLPEG_DLL - #define GRAPHQLPEG_EXPORT __declspec(dllimport) - #endif // !IMPL_GRAPHQLPEG_DLL -#else // !GRAPHQL_DLLEXPORTS - #define GRAPHQLPEG_EXPORT -#endif // !GRAPHQL_DLLEXPORTS -// clang-format on +#include "internal/DllExports.h" #include #include diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index 5ff8cb07..b8249926 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -6,19 +6,8 @@ #ifndef GRAPHQLRESPONSE_H #define GRAPHQLRESPONSE_H -// clang-format off -#ifdef GRAPHQL_DLLEXPORTS - #ifdef IMPL_GRAPHQLRESPONSE_DLL - #define GRAPHQLRESPONSE_EXPORT __declspec(dllexport) - #else // !IMPL_GRAPHQLRESPONSE_DLL - #define GRAPHQLRESPONSE_EXPORT __declspec(dllimport) - #endif // !IMPL_GRAPHQLRESPONSE_DLL -#else // !GRAPHQL_DLLEXPORTS - #define GRAPHQLRESPONSE_EXPORT -#endif // !GRAPHQL_DLLEXPORTS -// clang-format on - -#include "graphqlservice/internal/Awaitable.h" +#include "internal/Awaitable.h" +#include "internal/DllExports.h" #include #include diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 0e7f2ea6..a412b1a4 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -6,24 +6,13 @@ #ifndef GRAPHQLSERVICE_H #define GRAPHQLSERVICE_H -// clang-format off -#ifdef GRAPHQL_DLLEXPORTS - #ifdef IMPL_GRAPHQLSERVICE_DLL - #define GRAPHQLSERVICE_EXPORT __declspec(dllexport) - #else // !IMPL_GRAPHQLSERVICE_DLL - #define GRAPHQLSERVICE_EXPORT __declspec(dllimport) - #endif // !IMPL_GRAPHQLSERVICE_DLL -#else // !GRAPHQL_DLLEXPORTS - #define GRAPHQLSERVICE_EXPORT -#endif // !GRAPHQL_DLLEXPORTS -// clang-format on - -#include "graphqlservice/GraphQLParse.h" -#include "graphqlservice/GraphQLResponse.h" - -#include "graphqlservice/internal/Awaitable.h" -#include "graphqlservice/internal/SortedMap.h" -#include "graphqlservice/internal/Version.h" +#include "GraphQLParse.h" +#include "GraphQLResponse.h" + +#include "internal/Awaitable.h" +#include "internal/DllExports.h" +#include "internal/SortedMap.h" +#include "internal/Version.h" #include #include diff --git a/include/graphqlservice/JSONResponse.h b/include/graphqlservice/JSONResponse.h index c264fd82..aeb8609c 100644 --- a/include/graphqlservice/JSONResponse.h +++ b/include/graphqlservice/JSONResponse.h @@ -6,19 +6,9 @@ #ifndef JSONRESPONSE_H #define JSONRESPONSE_H -// clang-format off -#ifdef GRAPHQL_DLLEXPORTS - #ifdef IMPL_JSONRESPONSE_DLL - #define JSONRESPONSE_EXPORT __declspec(dllexport) - #else // !IMPL_JSONRESPONSE_DLL - #define JSONRESPONSE_EXPORT __declspec(dllimport) - #endif // !IMPL_JSONRESPONSE_DLL -#else // !GRAPHQL_DLLEXPORTS - #define JSONRESPONSE_EXPORT -#endif // !GRAPHQL_DLLEXPORTS -// clang-format on - -#include "graphqlservice/GraphQLResponse.h" +#include "GraphQLResponse.h" + +#include "internal/DllExports.h" namespace graphql::response { diff --git a/include/graphqlservice/internal/Base64.h b/include/graphqlservice/internal/Base64.h index 163e1e84..5aaf1713 100644 --- a/include/graphqlservice/internal/Base64.h +++ b/include/graphqlservice/internal/Base64.h @@ -6,17 +6,7 @@ #ifndef GRAPHQLBASE64_H #define GRAPHQLBASE64_H -// clang-format off -#ifdef GRAPHQL_DLLEXPORTS - #ifdef IMPL_GRAPHQLRESPONSE_DLL - #define GRAPHQLRESPONSE_EXPORT __declspec(dllexport) - #else // !IMPL_GRAPHQLRESPONSE_DLL - #define GRAPHQLRESPONSE_EXPORT __declspec(dllimport) - #endif // !IMPL_GRAPHQLRESPONSE_DLL -#else // !GRAPHQL_DLLEXPORTS - #define GRAPHQLRESPONSE_EXPORT -#endif // !GRAPHQL_DLLEXPORTS -// clang-format on +#include "DllExports.h" #include #include diff --git a/include/graphqlservice/internal/DllExports.h b/include/graphqlservice/internal/DllExports.h new file mode 100644 index 00000000..b6cbfb39 --- /dev/null +++ b/include/graphqlservice/internal/DllExports.h @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#ifndef DLLEXPORTS_H +#define DLLEXPORTS_H + +// clang-format off +#ifdef GRAPHQL_DLLEXPORTS + #ifdef IMPL_GRAPHQLCLIENT_DLL + #define GRAPHQLCLIENT_EXPORT __declspec(dllexport) + #else // !IMPL_GRAPHQLCLIENT_DLL + #define GRAPHQLCLIENT_EXPORT __declspec(dllimport) + #endif // !IMPL_GRAPHQLCLIENT_DLL + + #ifdef IMPL_GRAPHQLPEG_DLL + #define GRAPHQLPEG_EXPORT __declspec(dllexport) + #else // !IMPL_GRAPHQLPEG_DLL + #define GRAPHQLPEG_EXPORT __declspec(dllimport) + #endif // !IMPL_GRAPHQLPEG_DLL + + #ifdef IMPL_GRAPHQLRESPONSE_DLL + #define GRAPHQLRESPONSE_EXPORT __declspec(dllexport) + #else // !IMPL_GRAPHQLRESPONSE_DLL + #define GRAPHQLRESPONSE_EXPORT __declspec(dllimport) + #endif // !IMPL_GRAPHQLRESPONSE_DLL + + #ifdef IMPL_GRAPHQLSERVICE_DLL + #define GRAPHQLSERVICE_EXPORT __declspec(dllexport) + #else // !IMPL_GRAPHQLSERVICE_DLL + #define GRAPHQLSERVICE_EXPORT __declspec(dllimport) + #endif // !IMPL_GRAPHQLSERVICE_DLL + + #ifdef IMPL_JSONRESPONSE_DLL + #define JSONRESPONSE_EXPORT __declspec(dllexport) + #else // !IMPL_JSONRESPONSE_DLL + #define JSONRESPONSE_EXPORT __declspec(dllimport) + #endif // !IMPL_JSONRESPONSE_DLL +#else // !GRAPHQL_DLLEXPORTS + #define GRAPHQLCLIENT_EXPORT + #define GRAPHQLPEG_EXPORT + #define GRAPHQLRESPONSE_EXPORT + #define GRAPHQLSERVICE_EXPORT + #define JSONRESPONSE_EXPORT +#endif // !GRAPHQL_DLLEXPORTS +// clang-format on + +#endif // DLLEXPORTS_H diff --git a/include/graphqlservice/internal/Grammar.h b/include/graphqlservice/internal/Grammar.h index 8f3824b1..89bfe0a2 100644 --- a/include/graphqlservice/internal/Grammar.h +++ b/include/graphqlservice/internal/Grammar.h @@ -9,7 +9,7 @@ #ifndef GRAPHQLGRAMMAR_H #define GRAPHQLGRAMMAR_H -#include "graphqlservice/internal/SyntaxTree.h" +#include "SyntaxTree.h" #include diff --git a/include/graphqlservice/internal/Introspection.h b/include/graphqlservice/internal/Introspection.h index 885af384..e7b926f1 100644 --- a/include/graphqlservice/internal/Introspection.h +++ b/include/graphqlservice/internal/Introspection.h @@ -8,7 +8,8 @@ #include "graphqlservice/introspection/IntrospectionSchema.h" -#include "graphqlservice/internal/Schema.h" +#include "DllExports.h" +#include "Schema.h" namespace graphql::introspection { diff --git a/include/graphqlservice/internal/Schema.h b/include/graphqlservice/internal/Schema.h index 24480943..661ef00f 100644 --- a/include/graphqlservice/internal/Schema.h +++ b/include/graphqlservice/internal/Schema.h @@ -6,9 +6,12 @@ #ifndef GRAPHQLSCHEMA_H #define GRAPHQLSCHEMA_H -#include "graphqlservice/GraphQLService.h" +#include "DllExports.h" +#include "SortedMap.h" +#include "Version.h" #include +#include namespace graphql { namespace introspection { diff --git a/include/graphqlservice/internal/SyntaxTree.h b/include/graphqlservice/internal/SyntaxTree.h index 7e9be03a..fad8ef41 100644 --- a/include/graphqlservice/internal/SyntaxTree.h +++ b/include/graphqlservice/internal/SyntaxTree.h @@ -6,7 +6,7 @@ #ifndef GRAPHQLSYNTAXTREE_H #define GRAPHQLSYNTAXTREE_H -#include "graphqlservice/GraphQLParse.h" +#include "DllExports.h" #define TAO_PEGTL_NAMESPACE tao::graphqlpeg diff --git a/include/graphqlservice/introspection/IntrospectionSchema.h b/include/graphqlservice/introspection/IntrospectionSchema.h index 4adaa9af..363d67f2 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.h +++ b/include/graphqlservice/introspection/IntrospectionSchema.h @@ -8,6 +8,9 @@ #ifndef INTROSPECTIONSCHEMA_H #define INTROSPECTIONSCHEMA_H +#include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/GraphQLService.h" + #include "graphqlservice/internal/Schema.h" // Check if the library version is compatible with schemagen 4.5.0 diff --git a/samples/learn/schema/StarWarsSchema.h b/samples/learn/schema/StarWarsSchema.h index 01308601..2511eac0 100644 --- a/samples/learn/schema/StarWarsSchema.h +++ b/samples/learn/schema/StarWarsSchema.h @@ -8,6 +8,9 @@ #ifndef STARWARSSCHEMA_H #define STARWARSSCHEMA_H +#include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/GraphQLService.h" + #include "graphqlservice/internal/Schema.h" // Check if the library version is compatible with schemagen 4.5.0 diff --git a/samples/proxy/schema/ProxySchema.h b/samples/proxy/schema/ProxySchema.h index c1d565d3..eebe09e9 100644 --- a/samples/proxy/schema/ProxySchema.h +++ b/samples/proxy/schema/ProxySchema.h @@ -8,6 +8,9 @@ #ifndef PROXYSCHEMA_H #define PROXYSCHEMA_H +#include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/GraphQLService.h" + #include "graphqlservice/internal/Schema.h" // Check if the library version is compatible with schemagen 4.5.0 diff --git a/samples/today/nointrospection/TodaySchema.h b/samples/today/nointrospection/TodaySchema.h index ebcd3905..ef18f867 100644 --- a/samples/today/nointrospection/TodaySchema.h +++ b/samples/today/nointrospection/TodaySchema.h @@ -8,6 +8,9 @@ #ifndef TODAYSCHEMA_H #define TODAYSCHEMA_H +#include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/GraphQLService.h" + #include "graphqlservice/internal/Schema.h" // Check if the library version is compatible with schemagen 4.5.0 diff --git a/samples/today/schema/TodaySchema.h b/samples/today/schema/TodaySchema.h index ebcd3905..ef18f867 100644 --- a/samples/today/schema/TodaySchema.h +++ b/samples/today/schema/TodaySchema.h @@ -8,6 +8,9 @@ #ifndef TODAYSCHEMA_H #define TODAYSCHEMA_H +#include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/GraphQLService.h" + #include "graphqlservice/internal/Schema.h" // Check if the library version is compatible with schemagen 4.5.0 diff --git a/samples/validation/schema/ValidationSchema.h b/samples/validation/schema/ValidationSchema.h index be93c2b8..66208163 100644 --- a/samples/validation/schema/ValidationSchema.h +++ b/samples/validation/schema/ValidationSchema.h @@ -8,6 +8,9 @@ #ifndef VALIDATIONSCHEMA_H #define VALIDATIONSCHEMA_H +#include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/GraphQLService.h" + #include "graphqlservice/internal/Schema.h" // Check if the library version is compatible with schemagen 4.5.0 diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 59c41549..6feaea8d 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -109,7 +109,10 @@ bool Generator::outputHeader() const noexcept IncludeGuardScope includeGuard { headerFile, std::filesystem::path(_headerPath).filename().string() }; - headerFile << R"cpp(#include "graphqlservice/internal/Schema.h" + headerFile << R"cpp(#include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/GraphQLService.h" + +#include "graphqlservice/internal/Schema.h" // Check if the library version is compatible with schemagen )cpp" << graphql::internal::MajorVersion << R"cpp(.)cpp" << graphql::internal::MinorVersion diff --git a/src/introspection/IntrospectionSchema.h b/src/introspection/IntrospectionSchema.h index 4adaa9af..363d67f2 100644 --- a/src/introspection/IntrospectionSchema.h +++ b/src/introspection/IntrospectionSchema.h @@ -8,6 +8,9 @@ #ifndef INTROSPECTIONSCHEMA_H #define INTROSPECTIONSCHEMA_H +#include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/GraphQLService.h" + #include "graphqlservice/internal/Schema.h" // Check if the library version is compatible with schemagen 4.5.0 From 7dc77fafc6410c77740773984cedfbf68fde569b Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 14:37:23 -0700 Subject: [PATCH 015/123] fix(includes): missing standard headers --- include/graphqlservice/internal/Schema.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/graphqlservice/internal/Schema.h b/include/graphqlservice/internal/Schema.h index 661ef00f..bdc87926 100644 --- a/include/graphqlservice/internal/Schema.h +++ b/include/graphqlservice/internal/Schema.h @@ -10,7 +10,10 @@ #include "SortedMap.h" #include "Version.h" +#include +#include #include +#include #include namespace graphql { From 64452a34ee518e9351d870a6affad26d90238986 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 11 Sep 2024 21:35:48 -0700 Subject: [PATCH 016/123] fix: replace C-style size_t with std::size_t --- cmake/Version.h.in | 7 +- doc/responses.md | 4 +- include/ClientGenerator.h | 32 +- include/SchemaGenerator.h | 50 ++-- include/SchemaLoader.h | 52 ++-- include/Validation.h | 6 +- include/graphqlservice/GraphQLParse.h | 13 +- include/graphqlservice/GraphQLResponse.h | 30 +- include/graphqlservice/GraphQLService.h | 23 +- include/graphqlservice/internal/Schema.h | 2 +- include/graphqlservice/internal/SortedMap.h | 52 ++-- include/graphqlservice/internal/SyntaxTree.h | 7 +- include/graphqlservice/internal/Version.h | 7 +- samples/client/benchmark.cpp | 9 +- samples/client/benchmark/BenchmarkClient.cpp | 1 + .../client/multiple/MultipleQueriesClient.cpp | 3 +- samples/client/mutate/MutateClient.cpp | 3 +- .../client/nestedinput/NestedInputClient.cpp | 1 + samples/client/query/QueryClient.cpp | 1 + samples/client/subscribe/SubscribeClient.cpp | 1 + samples/learn/schema/StarWarsSchema.cpp | 9 +- samples/proxy/query/ProxyClient.cpp | 1 + samples/proxy/schema/ProxySchema.cpp | 1 + samples/today/TodayMock.cpp | 14 +- samples/today/TodayMock.h | 38 +-- samples/today/benchmark.cpp | 8 +- samples/today/nointrospection/TodaySchema.cpp | 11 +- samples/today/schema/TodaySchema.cpp | 11 +- .../validation/schema/ValidationSchema.cpp | 13 +- src/Base64.cpp | 3 +- src/ClientGenerator.cpp | 10 +- src/GraphQLClient.cpp | 6 +- src/GraphQLResponse.cpp | 63 ++-- src/GraphQLService.cpp | 20 +- src/RequestLoader.cpp | 15 +- src/SchemaGenerator.cpp | 19 +- src/SchemaLoader.cpp | 25 +- src/SyntaxTree.cpp | 35 +-- src/Validation.cpp | 3 +- src/introspection/IntrospectionSchema.cpp | 59 ++-- test/ArgumentTests.cpp | 20 +- test/ClientTests.cpp | 36 ++- test/CoroutineTests.cpp | 83 +++--- test/NoIntrospectionTests.cpp | 28 +- test/PegtlCombinedTests.cpp | 4 +- test/PegtlExecutableTests.cpp | 7 +- test/PegtlSchemaTests.cpp | 4 +- test/TodayTests.cpp | 275 ++++++++++-------- test/ValidationTests.cpp | 177 +++++------ 49 files changed, 691 insertions(+), 611 deletions(-) diff --git a/cmake/Version.h.in b/cmake/Version.h.in index ce86ef57..e2bdc9c8 100644 --- a/cmake/Version.h.in +++ b/cmake/Version.h.in @@ -6,15 +6,16 @@ #ifndef GRAPHQLVERSION_H #define GRAPHQLVERSION_H +#include #include namespace graphql::internal { constexpr std::string_view FullVersion { "@PROJECT_VERSION@" }; -constexpr size_t MajorVersion = @PROJECT_VERSION_MAJOR@; -constexpr size_t MinorVersion = @PROJECT_VERSION_MINOR@; -constexpr size_t PatchVersion = @PROJECT_VERSION_PATCH@; +constexpr std::size_t MajorVersion = @PROJECT_VERSION_MAJOR@; +constexpr std::size_t MinorVersion = @PROJECT_VERSION_MINOR@; +constexpr std::size_t PatchVersion = @PROJECT_VERSION_PATCH@; } // namespace graphql::internal diff --git a/doc/responses.md b/doc/responses.md index 079d18c6..d328f5cf 100644 --- a/doc/responses.md +++ b/doc/responses.md @@ -41,8 +41,8 @@ specializations. ## Map and List -`Map` and `List` types enable collection methods like `reserve(size_t)`, +`Map` and `List` types enable collection methods like `reserve(std::size_t)`, `size()`, and `emplace_back(...)`. `Map` additionally implements `begin()` and `end()` for range-based for loops and `find(const std::string&)` and `operator[](const std::string&)` for key-based lookups. `List` has an -`operator[](size_t)` for index-based instead of key-based lookups. \ No newline at end of file +`operator[](std::size_t)` for index-based instead of key-based lookups. \ No newline at end of file diff --git a/include/ClientGenerator.h b/include/ClientGenerator.h index 6083e526..2b3af1f2 100644 --- a/include/ClientGenerator.h +++ b/include/ClientGenerator.h @@ -9,6 +9,8 @@ #include "RequestLoader.h" #include "SchemaLoader.h" +#include + namespace graphql::generator::client { struct [[nodiscard("unnecessary construction")]] GeneratorPaths @@ -27,9 +29,8 @@ class [[nodiscard("unnecessary construction")]] Generator { public: // Initialize the generator with the introspection client or a custom GraphQL client. - explicit Generator(SchemaOptions && schemaOptions, - RequestOptions && requestOptions, - GeneratorOptions && options); + explicit Generator( + SchemaOptions&& schemaOptions, RequestOptions&& requestOptions, GeneratorOptions&& options); // Run the generator and return a list of filenames that were output. [[nodiscard("unnecessary memory copy")]] std::vector Build() const noexcept; @@ -43,24 +44,21 @@ class [[nodiscard("unnecessary construction")]] Generator [[nodiscard("unnecessary call")]] const std::string& getOperationNamespace( const Operation& operation) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getResponseFieldCppType( - const ResponseField& responseField, - std::string_view currentScope = {}) const noexcept; + const ResponseField& responseField, std::string_view currentScope = {}) const noexcept; [[nodiscard("unnecessary call")]] bool outputHeader() const noexcept; - void outputRequestComment(std::ostream & headerFile) const noexcept; - void outputGetRequestDeclaration(std::ostream & headerFile) const noexcept; - void outputGetOperationNameDeclaration(std::ostream & headerFile) const noexcept; - [[nodiscard("unnecessary call")]] bool outputResponseFieldType(std::ostream & headerFile, - const ResponseField& responseField, - size_t indent = 0) const noexcept; + void outputRequestComment(std::ostream& headerFile) const noexcept; + void outputGetRequestDeclaration(std::ostream& headerFile) const noexcept; + void outputGetOperationNameDeclaration(std::ostream& headerFile) const noexcept; + [[nodiscard("unnecessary call")]] bool outputResponseFieldType(std::ostream& headerFile, + const ResponseField& responseField, std::size_t indent = 0) const noexcept; [[nodiscard("unnecessary call")]] bool outputSource() const noexcept; - void outputGetRequestImplementation(std::ostream & sourceFile) const noexcept; - void outputGetOperationNameImplementation(std::ostream & sourceFile, const Operation& operation) - const noexcept; - bool outputModifiedResponseImplementation(std::ostream & sourceFile, - const std::string& outerScope, - const ResponseField& responseField) const noexcept; + void outputGetRequestImplementation(std::ostream& sourceFile) const noexcept; + void outputGetOperationNameImplementation( + std::ostream& sourceFile, const Operation& operation) const noexcept; + bool outputModifiedResponseImplementation(std::ostream& sourceFile, + const std::string& outerScope, const ResponseField& responseField) const noexcept; [[nodiscard("unnecessary memory copy")]] static std::string getTypeModifierList( const TypeModifierStack& modifiers) noexcept; diff --git a/include/SchemaGenerator.h b/include/SchemaGenerator.h index f0ba1bf0..20b12a64 100644 --- a/include/SchemaGenerator.h +++ b/include/SchemaGenerator.h @@ -8,6 +8,8 @@ #include "SchemaLoader.h" +#include + namespace graphql::generator::schema { struct [[nodiscard("unnecessary construction")]] GeneratorPaths @@ -28,7 +30,7 @@ class [[nodiscard("unnecessary construction")]] Generator { public: // Initialize the generator with the introspection schema or a custom GraphQL schema. - explicit Generator(SchemaOptions && schemaOptions, GeneratorOptions && options); + explicit Generator(SchemaOptions&& schemaOptions, GeneratorOptions&& options); // Run the generator and return a list of filenames that were output. [[nodiscard("unnecessary construction")]] std::vector Build() const noexcept; @@ -40,12 +42,11 @@ class [[nodiscard("unnecessary construction")]] Generator [[nodiscard("unnecessary memory copy")]] std::string getSourcePath() const noexcept; [[nodiscard("unnecessary call")]] bool outputHeader() const noexcept; - void outputInterfaceDeclaration(std::ostream & headerFile, std::string_view cppType) const; - void outputObjectImplements(std::ostream & headerFile, const ObjectType& objectType) const; - void outputObjectStubs(std::ostream & headerFile, const ObjectType& objectType) const; - void outputObjectDeclaration(std::ostream & headerFile, - const ObjectType& objectType, - bool isQueryType) const; + void outputInterfaceDeclaration(std::ostream& headerFile, std::string_view cppType) const; + void outputObjectImplements(std::ostream& headerFile, const ObjectType& objectType) const; + void outputObjectStubs(std::ostream& headerFile, const ObjectType& objectType) const; + void outputObjectDeclaration( + std::ostream& headerFile, const ObjectType& objectType, bool isQueryType) const; [[nodiscard("unnecessary memory copy")]] std::string getFieldDeclaration( const InputField& inputField) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getFieldDeclaration( @@ -54,26 +55,21 @@ class [[nodiscard("unnecessary construction")]] Generator const OutputField& outputField) const noexcept; [[nodiscard("unnecessary call")]] bool outputSource() const noexcept; - void outputInterfaceImplementation(std::ostream & sourceFile, std::string_view cppType) const; - void outputInterfaceIntrospection(std::ostream & sourceFile, const InterfaceType& interfaceType) - const; - void outputUnionIntrospection(std::ostream & sourceFile, const UnionType& unionType) const; - void outputObjectImplementation(std::ostream & sourceFile, - const ObjectType& objectType, - bool isQueryType) const; - void outputObjectIntrospection(std::ostream & sourceFile, const ObjectType& objectType) const; - void outputIntrospectionInterfaces(std::ostream & sourceFile, - std::string_view cppType, + void outputInterfaceImplementation(std::ostream& sourceFile, std::string_view cppType) const; + void outputInterfaceIntrospection( + std::ostream& sourceFile, const InterfaceType& interfaceType) const; + void outputUnionIntrospection(std::ostream& sourceFile, const UnionType& unionType) const; + void outputObjectImplementation( + std::ostream& sourceFile, const ObjectType& objectType, bool isQueryType) const; + void outputObjectIntrospection(std::ostream& sourceFile, const ObjectType& objectType) const; + void outputIntrospectionInterfaces(std::ostream& sourceFile, std::string_view cppType, const std::vector& interfaces) const; - void outputIntrospectionFields(std::ostream & sourceFile, - std::string_view cppType, - const OutputFieldList& fields) const; - [[nodiscard("unnecessary memory copy")]] std::string getArgumentDefaultValue(size_t level, - const response::Value& defaultValue) const noexcept; + void outputIntrospectionFields( + std::ostream& sourceFile, std::string_view cppType, const OutputFieldList& fields) const; + [[nodiscard("unnecessary memory copy")]] std::string getArgumentDefaultValue( + std::size_t level, const response::Value& defaultValue) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getArgumentDeclaration( - const InputField& argument, - const char* prefixToken, - const char* argumentsToken, + const InputField& argument, const char* prefixToken, const char* argumentsToken, const char* defaultToken) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getArgumentAccessType( const InputField& argument) const noexcept; @@ -81,8 +77,8 @@ class [[nodiscard("unnecessary construction")]] Generator const OutputField& result) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getTypeModifiers( const TypeModifierStack& modifiers) const noexcept; - [[nodiscard("unnecessary memory copy")]] std::string getIntrospectionType(std::string_view type, - const TypeModifierStack& modifiers) const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getIntrospectionType( + std::string_view type, const TypeModifierStack& modifiers) const noexcept; [[nodiscard("unnecessary memory copy")]] std::vector outputSeparateFiles() const noexcept; diff --git a/include/SchemaLoader.h b/include/SchemaLoader.h index 9aa73444..181de219 100644 --- a/include/SchemaLoader.h +++ b/include/SchemaLoader.h @@ -14,6 +14,7 @@ #include "graphqlservice/internal/Grammar.h" #include +#include #include #include @@ -31,14 +32,14 @@ enum class [[nodiscard("unnecessary conversion")]] BuiltinType { using BuiltinTypeMap = std::map; // These are the C++ types we'll use for them. -using CppTypeMap = std::array(BuiltinType::ID) + 1>; +using CppTypeMap = std::array(BuiltinType::ID) + 1>; // Keep track of the positions of each type declaration in the file. using PositionMap = std::unordered_map; // For all of the named types we track, we want to keep them in order in a vector but // be able to lookup their offset quickly by name. -using TypeNameMap = std::unordered_map; +using TypeNameMap = std::unordered_map; // Scalar types are opaque to the generator, it's up to the service implementation // to handle parsing, validating, and serializing them. We just need to track which @@ -216,7 +217,7 @@ class [[nodiscard("unnecessary construction")]] SchemaLoader { public: // Initialize the loader with the introspection schema or a custom GraphQL schema. - explicit SchemaLoader(SchemaOptions && schemaOptions); + explicit SchemaLoader(SchemaOptions&& schemaOptions); [[nodiscard("unnecessary call")]] bool isIntrospection() const noexcept; [[nodiscard("unnecessary call")]] std::string_view getSchemaDescription() const noexcept; @@ -232,22 +233,22 @@ class [[nodiscard("unnecessary construction")]] SchemaLoader [[nodiscard("unnecessary call")]] const tao::graphqlpeg::position& getTypePosition( std::string_view type) const; - [[nodiscard("unnecessary call")]] size_t getScalarIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getScalarIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const ScalarTypeList& getScalarTypes() const noexcept; - [[nodiscard("unnecessary call")]] size_t getEnumIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getEnumIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const EnumTypeList& getEnumTypes() const noexcept; - [[nodiscard("unnecessary call")]] size_t getInputIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getInputIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const InputTypeList& getInputTypes() const noexcept; - [[nodiscard("unnecessary call")]] size_t getUnionIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getUnionIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const UnionTypeList& getUnionTypes() const noexcept; - [[nodiscard("unnecessary call")]] size_t getInterfaceIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getInterfaceIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const InterfaceTypeList& getInterfaceTypes() const noexcept; - [[nodiscard("unnecessary call")]] size_t getObjectIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getObjectIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const ObjectTypeList& getObjectTypes() const noexcept; [[nodiscard("unnecessary call")]] const DirectiveList& getDirectives() const noexcept; @@ -259,12 +260,12 @@ class [[nodiscard("unnecessary construction")]] SchemaLoader [[nodiscard("unnecessary call")]] static std::string_view getSafeCppName( std::string_view type) noexcept; - [[nodiscard("unnecessary call")]] std::string_view getCppType(std::string_view type) - const noexcept; - [[nodiscard("unnecessary memory copy")]] std::string getInputCppType(const InputField& field) - const noexcept; - [[nodiscard("unnecessary memory copy")]] std::string getOutputCppType(const OutputField& field) - const noexcept; + [[nodiscard("unnecessary call")]] std::string_view getCppType( + std::string_view type) const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getInputCppType( + const InputField& field) const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getOutputCppType( + const OutputField& field) const noexcept; [[nodiscard("unnecessary memory copy")]] static std::string getOutputCppAccessor( const OutputField& field) noexcept; @@ -296,32 +297,29 @@ class [[nodiscard("unnecessary construction")]] SchemaLoader void visitObjectTypeExtension(const peg::ast_node& objectTypeExtension); void visitDirectiveDefinition(const peg::ast_node& directiveDefinition); - static void blockReservedName(std::string_view name, - std::optional position = std::nullopt); + static void blockReservedName( + std::string_view name, std::optional position = std::nullopt); [[nodiscard("unnecessary memory copy")]] static OutputFieldList getOutputFields( const peg::ast_node::children_t& fields); [[nodiscard("unnecessary memory copy")]] static InputFieldList getInputFields( const peg::ast_node::children_t& fields); void validateSchema(); - void fixupOutputFieldList(OutputFieldList & fields, + void fixupOutputFieldList(OutputFieldList& fields, const std::optional>& interfaceFields, const std::optional& accessor); - void fixupInputFieldList(InputFieldList & fields); + void fixupInputFieldList(InputFieldList& fields); void reorderInputTypeDependencies(); void validateImplementedInterfaces() const; [[nodiscard("unnecessary call")]] const InterfaceType& findInterfaceType( - std::string_view typeName, - std::string_view interfaceName) const; - void validateInterfaceFields(std::string_view typeName, - std::string_view interfaceName, + std::string_view typeName, std::string_view interfaceName) const; + void validateInterfaceFields(std::string_view typeName, std::string_view interfaceName, const OutputFieldList& typeFields) const; - void validateTransitiveInterfaces(std::string_view typeName, - const std::vector& interfaces) const; + void validateTransitiveInterfaces( + std::string_view typeName, const std::vector& interfaces) const; [[nodiscard("unnecessary memory copy")]] static std::string getJoinedCppName( - std::string_view prefix, - std::string_view fieldName) noexcept; + std::string_view prefix, std::string_view fieldName) noexcept; static const std::string_view s_introspectionNamespace; static const BuiltinTypeMap s_builtinTypes; diff --git a/include/Validation.h b/include/Validation.h index 5b11057c..1dd48c77 100644 --- a/include/Validation.h +++ b/include/Validation.h @@ -10,6 +10,8 @@ #include "graphqlservice/internal/Schema.h" +#include + namespace graphql::service { using ValidateType = std::optional>; @@ -257,8 +259,8 @@ class [[nodiscard("unnecessary construction")]] ValidateExecutableVisitor VariableDefinitions _variableDefinitions; VariableSet _referencedVariables; FragmentSet _fragmentStack; - size_t _fieldCount = 0; - size_t _introspectionFieldCount = 0; + std::size_t _fieldCount = 0; + std::size_t _introspectionFieldCount = 0; TypeFields _typeFields; InputTypeFields _inputTypeFields; ValidateType _scopedType; diff --git a/include/graphqlservice/GraphQLParse.h b/include/graphqlservice/GraphQLParse.h index cfd8682f..4336fb8e 100644 --- a/include/graphqlservice/GraphQLParse.h +++ b/include/graphqlservice/GraphQLParse.h @@ -8,6 +8,7 @@ #include "internal/DllExports.h" +#include #include #include @@ -26,22 +27,22 @@ struct [[nodiscard("unnecessary parse")]] ast // By default, we want to limit the depth of nested nodes. You can override this with // another value for the depthLimit parameter in these parse functions. -constexpr size_t c_defaultDepthLimit = 25; +constexpr std::size_t c_defaultDepthLimit = 25; [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT ast parseSchemaString( - std::string_view input, size_t depthLimit = c_defaultDepthLimit); + std::string_view input, std::size_t depthLimit = c_defaultDepthLimit); [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT ast parseSchemaFile( - std::string_view filename, size_t depthLimit = c_defaultDepthLimit); + std::string_view filename, std::size_t depthLimit = c_defaultDepthLimit); [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT ast parseString( - std::string_view input, size_t depthLimit = c_defaultDepthLimit); + std::string_view input, std::size_t depthLimit = c_defaultDepthLimit); [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT ast parseFile( - std::string_view filename, size_t depthLimit = c_defaultDepthLimit); + std::string_view filename, std::size_t depthLimit = c_defaultDepthLimit); } // namespace peg [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT peg::ast operator"" _graphql( - const char* text, size_t size); + const char* text, std::size_t size); } // namespace graphql diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index b8249926..777aae54 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -9,6 +9,7 @@ #include "internal/Awaitable.h" #include "internal/DllExports.h" +#include #include #include #include @@ -55,7 +56,7 @@ struct [[nodiscard("unnecessary conversion")]] IdType GRAPHQLRESPONSE_EXPORT ~IdType(); // Implicit ByteData constructors - GRAPHQLRESPONSE_EXPORT IdType(size_t count, typename ByteData::value_type value = 0); + GRAPHQLRESPONSE_EXPORT IdType(std::size_t count, typename ByteData::value_type value = 0); GRAPHQLRESPONSE_EXPORT IdType(std::initializer_list values); template IdType(InputIt begin, InputIt end); @@ -90,20 +91,21 @@ struct [[nodiscard("unnecessary conversion")]] IdType // Shared accessors [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT bool empty() const noexcept; - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT size_t size() const noexcept; - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT size_t max_size() const noexcept; - GRAPHQLRESPONSE_EXPORT void reserve(size_t new_cap); - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT size_t capacity() const noexcept; + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::size_t size() const noexcept; + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::size_t max_size() const noexcept; + GRAPHQLRESPONSE_EXPORT void reserve(std::size_t new_cap); + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::size_t capacity() const noexcept; GRAPHQLRESPONSE_EXPORT void shrink_to_fit(); GRAPHQLRESPONSE_EXPORT void clear() noexcept; // ByteData accessors [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT const std::uint8_t& at( - size_t pos) const; - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::uint8_t& at(size_t pos); + std::size_t pos) const; + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::uint8_t& at(std::size_t pos); [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT const std::uint8_t& operator[]( - size_t pos) const; - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::uint8_t& operator[](size_t pos); + std::size_t pos) const; + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::uint8_t& operator[]( + std::size_t pos); [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT const std::uint8_t& front() const; [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::uint8_t& front(); [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT const std::uint8_t& back() const; @@ -250,8 +252,8 @@ struct [[nodiscard("unnecessary conversion")]] Value [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT bool maybe_id() const noexcept; // Valid for Type::Map or Type::List - GRAPHQLRESPONSE_EXPORT void reserve(size_t count); - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT size_t size() const; + GRAPHQLRESPONSE_EXPORT void reserve(std::size_t count); + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::size_t size() const; // Valid for Type::Map GRAPHQLRESPONSE_EXPORT bool emplace_back(std::string&& name, Value&& value); @@ -265,7 +267,7 @@ struct [[nodiscard("unnecessary conversion")]] Value // Valid for Type::List GRAPHQLRESPONSE_EXPORT void emplace_back(Value&& value); [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT const Value& operator[]( - size_t index) const; + std::size_t index) const; // Specialized for all single-value Types. template @@ -286,7 +288,7 @@ struct [[nodiscard("unnecessary conversion")]] Value [[nodiscard("unnecessary call")]] bool operator==(const MapData& rhs) const; MapType map; - std::vector members; + std::vector members; }; // Type::String @@ -461,7 +463,7 @@ class [[nodiscard("unnecessary construction")]] Writer final template Writer(std::unique_ptr writer) noexcept : _concept { std::static_pointer_cast( - std::make_shared>(std::move(writer))) } + std::make_shared>(std::move(writer))) } { } diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index a412b1a4..7fb7b77c 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -45,19 +46,19 @@ namespace service { // Errors should have a message string, and optional locations and a path. struct [[nodiscard("unnecessary construction")]] schema_location { - size_t line = 0; - size_t column = 1; + std::size_t line = 0; + std::size_t column = 1; }; // The implementation details of the error path should be opaque to client code. It is carried along // with the SelectionSetParams and automatically added to any schema errors or exceptions thrown // from an accessor as part of error reporting. -using path_segment = std::variant; +using path_segment = std::variant; struct [[nodiscard("unnecessary construction")]] field_path { std::optional> parent; - std::variant segment; + std::variant segment; }; using error_path = std::vector; @@ -1147,7 +1148,7 @@ struct ModifiedResult children.reserve(awaitedResult.size()); params.errorPath = std::make_optional( field_path { parentPath ? std::make_optional(std::cref(*parentPath)) : std::nullopt, - path_segment { size_t { 0 } } }); + path_segment { std::size_t { 0 } } }); using vector_type = std::decay_t; @@ -1161,7 +1162,7 @@ struct ModifiedResult { children.push_back( ModifiedResult::convert(std::move(entry), ResolverParams(params))); - ++std::get(params.errorPath->segment); + ++std::get(params.errorPath->segment); } } else @@ -1170,14 +1171,14 @@ struct ModifiedResult { children.push_back( ModifiedResult::convert(std::move(entry), ResolverParams(params))); - ++std::get(params.errorPath->segment); + ++std::get(params.errorPath->segment); } } ResolverResult document { response::Value { response::Type::List } }; document.data.reserve(children.size()); - std::get(params.errorPath->segment) = 0; + std::get(params.errorPath->segment) = 0; for (auto& child : children) { @@ -1215,7 +1216,7 @@ struct ModifiedResult buildErrorPath(params.errorPath) }); } - ++std::get(params.errorPath->segment); + ++std::get(params.errorPath->segment); } co_return document; @@ -1253,7 +1254,7 @@ struct ModifiedResult throw schema_exception { { R"ex(not a valid List value)ex" } }; } - for (size_t i = 0; i < value.size(); ++i) + for (std::size_t i = 0; i < value.size(); ++i) { ModifiedResult::validateScalar(value[i]); } @@ -1329,7 +1330,7 @@ using ObjectResult = ModifiedResult; using SubscriptionCallback = std::function; // Subscriptions are stored in maps using these keys. -using SubscriptionKey = size_t; +using SubscriptionKey = std::size_t; using SubscriptionName = std::string; using AwaitableSubscribe = internal::Awaitable; diff --git a/include/graphqlservice/internal/Schema.h b/include/graphqlservice/internal/Schema.h index bdc87926..801d3eda 100644 --- a/include/graphqlservice/internal/Schema.h +++ b/include/graphqlservice/internal/Schema.h @@ -81,7 +81,7 @@ class [[nodiscard("unnecessary construction")]] Schema : public std::enable_shar std::shared_ptr _query; std::shared_ptr _mutation; std::shared_ptr _subscription; - internal::string_view_map _typeMap; + internal::string_view_map _typeMap; std::vector>> _types; std::vector> _directives; std::shared_mutex _nonNullWrappersMutex; diff --git a/include/graphqlservice/internal/SortedMap.h b/include/graphqlservice/internal/SortedMap.h index 50e49dec..7fbb39c6 100644 --- a/include/graphqlservice/internal/SortedMap.h +++ b/include/graphqlservice/internal/SortedMap.h @@ -7,6 +7,7 @@ #define GRAPHQLSORTEDMAP_H #include +#include #include #include #include @@ -67,7 +68,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map constexpr sorted_map() noexcept = default; constexpr sorted_map(const sorted_map& other) = default; - sorted_map(sorted_map && other) noexcept = default; + sorted_map(sorted_map&& other) noexcept = default; constexpr sorted_map(std::initializer_list> init) : _data { init } @@ -82,18 +83,18 @@ class [[nodiscard("unnecessary construction")]] sorted_map sorted_map& operator=(const sorted_map& rhs) = default; sorted_map& operator=(sorted_map&& rhs) noexcept = default; - [[nodiscard("unnecessary call")]] constexpr bool operator==(const sorted_map& rhs) - const noexcept + [[nodiscard("unnecessary call")]] constexpr bool operator==( + const sorted_map& rhs) const noexcept { return _data == rhs._data; } - void reserve(size_t size) + void reserve(std::size_t size) { _data.reserve(size); } - [[nodiscard("unnecessary call")]] constexpr size_t capacity() const noexcept + [[nodiscard("unnecessary call")]] constexpr std::size_t capacity() const noexcept { return _data.capacity(); } @@ -108,7 +109,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map return _data.empty(); } - [[nodiscard("unnecessary call")]] constexpr size_t size() const noexcept + [[nodiscard("unnecessary call")]] constexpr std::size_t size() const noexcept { return _data.size(); } @@ -141,7 +142,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map } template - [[nodiscard("unnecessary call")]] constexpr const_iterator find(KeyArg && keyArg) const noexcept + [[nodiscard("unnecessary call")]] constexpr const_iterator find(KeyArg&& keyArg) const noexcept { const K key { std::forward(keyArg) }; @@ -149,7 +150,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map } template - std::pair emplace(KeyArg && keyArg, ValueArgs && ... args) noexcept + std::pair emplace(KeyArg&& keyArg, ValueArgs&&... args) noexcept { K key { std::forward(keyArg) }; const auto [itr, itrEnd] = sorted_map_equal_range(_data.begin(), _data.end(), key); @@ -176,7 +177,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map } template - const_iterator erase(KeyArg && keyArg) noexcept + const_iterator erase(KeyArg&& keyArg) noexcept { const K key { std::forward(keyArg) }; @@ -203,7 +204,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map } template - [[nodiscard("unnecessary call")]] V& at(KeyArg && keyArg) + [[nodiscard("unnecessary call")]] V& at(KeyArg&& keyArg) { const K key { std::forward(keyArg) }; const auto [itr, itrEnd] = sorted_map_equal_range(_data.begin(), _data.end(), key); @@ -230,7 +231,7 @@ class [[nodiscard("unnecessary construction")]] sorted_set constexpr sorted_set() noexcept = default; constexpr sorted_set(const sorted_set& other) = default; - sorted_set(sorted_set && other) noexcept = default; + sorted_set(sorted_set&& other) noexcept = default; constexpr sorted_set(std::initializer_list init) : _data { init } @@ -243,18 +244,18 @@ class [[nodiscard("unnecessary construction")]] sorted_set sorted_set& operator=(const sorted_set& rhs) = default; sorted_set& operator=(sorted_set&& rhs) noexcept = default; - [[nodiscard("unnecessary call")]] constexpr bool operator==(const sorted_set& rhs) - const noexcept + [[nodiscard("unnecessary call")]] constexpr bool operator==( + const sorted_set& rhs) const noexcept { return _data == rhs._data; } - void reserve(size_t size) + void reserve(std::size_t size) { _data.reserve(size); } - [[nodiscard("unnecessary call")]] constexpr size_t capacity() const noexcept + [[nodiscard("unnecessary call")]] constexpr std::size_t capacity() const noexcept { return _data.capacity(); } @@ -269,7 +270,7 @@ class [[nodiscard("unnecessary construction")]] sorted_set return _data.empty(); } - [[nodiscard("unnecessary call")]] constexpr size_t size() const noexcept + [[nodiscard("unnecessary call")]] constexpr std::size_t size() const noexcept { return _data.size(); } @@ -304,7 +305,7 @@ class [[nodiscard("unnecessary construction")]] sorted_set } template - [[nodiscard("unnecessary call")]] constexpr const_iterator find(Arg && arg) const noexcept + [[nodiscard("unnecessary call")]] constexpr const_iterator find(Arg&& arg) const noexcept { const K key { std::forward(arg) }; @@ -312,7 +313,7 @@ class [[nodiscard("unnecessary construction")]] sorted_set } template - std::pair emplace(Arg && key) noexcept + std::pair emplace(Arg&& key) noexcept { const auto [itr, itrEnd] = std::equal_range(_data.begin(), _data.end(), key, [](K lhs, K rhs) noexcept { @@ -343,7 +344,7 @@ class [[nodiscard("unnecessary construction")]] sorted_set } template - const_iterator erase(Arg && arg) noexcept + const_iterator erase(Arg&& arg) noexcept { const K key { std::forward(arg) }; @@ -359,13 +360,14 @@ class [[nodiscard("unnecessary construction")]] sorted_set vector_type _data; }; -struct [[nodiscard("unnecessary construction")]] shorter_or_less { +struct [[nodiscard("unnecessary construction")]] shorter_or_less +{ [[nodiscard("unnecessary call")]] constexpr bool operator()( - std::string_view lhs, std::string_view rhs) - const noexcept { return lhs.size() == rhs.size() ? lhs < rhs : lhs.size() < rhs.size(); -} // namespace graphql::internal -} -; + std::string_view lhs, std::string_view rhs) const noexcept + { + return lhs.size() == rhs.size() ? lhs < rhs : lhs.size() < rhs.size(); + } // namespace graphql::internal +}; template using string_view_map = sorted_map; diff --git a/include/graphqlservice/internal/SyntaxTree.h b/include/graphqlservice/internal/SyntaxTree.h index fad8ef41..268eb544 100644 --- a/include/graphqlservice/internal/SyntaxTree.h +++ b/include/graphqlservice/internal/SyntaxTree.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -69,17 +70,17 @@ class [[nodiscard("unnecessary construction")]] ast_node : public parse_tree::ba } template - [[nodiscard("unnecessary call")]] static size_t type_hash() noexcept + [[nodiscard("unnecessary call")]] static std::size_t type_hash() noexcept { // This is cached in a static local variable per-specialization, but each module may have // its own instance of the specialization and the local variable. - static const size_t hash = std::hash {}(type_name()); + static const std::size_t hash = std::hash {}(type_name()); return hash; } std::string_view _type_name; - size_t _type_hash = 0; + std::size_t _type_hash = 0; using unescaped_t = std::variant; diff --git a/include/graphqlservice/internal/Version.h b/include/graphqlservice/internal/Version.h index 0009d7f2..2384ae15 100644 --- a/include/graphqlservice/internal/Version.h +++ b/include/graphqlservice/internal/Version.h @@ -6,15 +6,16 @@ #ifndef GRAPHQLVERSION_H #define GRAPHQLVERSION_H +#include #include namespace graphql::internal { constexpr std::string_view FullVersion { "4.5.8" }; -constexpr size_t MajorVersion = 4; -constexpr size_t MinorVersion = 5; -constexpr size_t PatchVersion = 8; +constexpr std::size_t MajorVersion = 4; +constexpr std::size_t MinorVersion = 5; +constexpr std::size_t PatchVersion = 8; } // namespace graphql::internal diff --git a/samples/client/benchmark.cpp b/samples/client/benchmark.cpp index 8e793a70..ad7f9537 100644 --- a/samples/client/benchmark.cpp +++ b/samples/client/benchmark.cpp @@ -5,6 +5,7 @@ #include "TodayMock.h" #include +#include #include #include #include @@ -17,7 +18,7 @@ using namespace graphql; using namespace std::literals; void outputOverview( - size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept + std::size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept { const auto requestsPerSecond = ((static_cast(iterations) @@ -60,14 +61,14 @@ void outputSegment( int main(int argc, char** argv) { - const size_t iterations = [](const char* arg) noexcept -> size_t { + const std::size_t iterations = [](const char* arg) noexcept -> std::size_t { if (arg) { const int parsed = std::atoi(arg); if (parsed > 0) { - return static_cast(parsed); + return static_cast(parsed); } } @@ -91,7 +92,7 @@ int main(int argc, char** argv) auto query = GetRequestObject(); const auto& name = GetOperationName(); - for (size_t i = 0; i < iterations; ++i) + for (std::size_t i = 0; i < iterations; ++i) { const auto startResolve = std::chrono::steady_clock::now(); auto response = service->resolve({ query, name }).get(); diff --git a/samples/client/benchmark/BenchmarkClient.cpp b/samples/client/benchmark/BenchmarkClient.cpp index b7c48d94..4ce3e7d6 100644 --- a/samples/client/benchmark/BenchmarkClient.cpp +++ b/samples/client/benchmark/BenchmarkClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/samples/client/multiple/MultipleQueriesClient.cpp b/samples/client/multiple/MultipleQueriesClient.cpp index ed6de3e3..5383da2f 100644 --- a/samples/client/multiple/MultipleQueriesClient.cpp +++ b/samples/client/multiple/MultipleQueriesClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -739,7 +740,7 @@ response::Value Variable::serialize(TaskState&& value) response::Value result { response::Type::EnumValue }; - result.set(std::string { s_names[static_cast(value)] }); + result.set(std::string { s_names[static_cast(value)] }); return result; } diff --git a/samples/client/mutate/MutateClient.cpp b/samples/client/mutate/MutateClient.cpp index 027a03c9..019f2f43 100644 --- a/samples/client/mutate/MutateClient.cpp +++ b/samples/client/mutate/MutateClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -127,7 +128,7 @@ response::Value Variable::serialize(TaskState&& value) response::Value result { response::Type::EnumValue }; - result.set(std::string { s_names[static_cast(value)] }); + result.set(std::string { s_names[static_cast(value)] }); return result; } diff --git a/samples/client/nestedinput/NestedInputClient.cpp b/samples/client/nestedinput/NestedInputClient.cpp index 2832d921..16708663 100644 --- a/samples/client/nestedinput/NestedInputClient.cpp +++ b/samples/client/nestedinput/NestedInputClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/samples/client/query/QueryClient.cpp b/samples/client/query/QueryClient.cpp index a5752587..61422c40 100644 --- a/samples/client/query/QueryClient.cpp +++ b/samples/client/query/QueryClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/samples/client/subscribe/SubscribeClient.cpp b/samples/client/subscribe/SubscribeClient.cpp index 6cbcbe52..cf76839b 100644 --- a/samples/client/subscribe/SubscribeClient.cpp +++ b/samples/client/subscribe/SubscribeClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/samples/learn/schema/StarWarsSchema.cpp b/samples/learn/schema/StarWarsSchema.cpp index c14d3696..a5d8e9e2 100644 --- a/samples/learn/schema/StarWarsSchema.cpp +++ b/samples/learn/schema/StarWarsSchema.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -55,7 +56,7 @@ service::AwaitableResolver Result::convert(service::AwaitableSca { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesEpisode[static_cast(value)] }); + resolvedResult.set(std::string { s_namesEpisode[static_cast(value)] }); return resolvedResult; }); @@ -175,9 +176,9 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(Mutation)gql"sv, typeMutation); typeEpisode->AddEnumValues({ - { service::s_namesEpisode[static_cast(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt }, - { service::s_namesEpisode[static_cast(learn::Episode::EMPIRE)], R"md()md"sv, std::nullopt }, - { service::s_namesEpisode[static_cast(learn::Episode::JEDI)], R"md()md"sv, std::nullopt } + { service::s_namesEpisode[static_cast(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt }, + { service::s_namesEpisode[static_cast(learn::Episode::EMPIRE)], R"md()md"sv, std::nullopt }, + { service::s_namesEpisode[static_cast(learn::Episode::JEDI)], R"md()md"sv, std::nullopt } }); typeReviewInput->AddInputValues({ diff --git a/samples/proxy/query/ProxyClient.cpp b/samples/proxy/query/ProxyClient.cpp index fdf41b70..04b6546c 100644 --- a/samples/proxy/query/ProxyClient.cpp +++ b/samples/proxy/query/ProxyClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/samples/proxy/schema/ProxySchema.cpp b/samples/proxy/schema/ProxySchema.cpp index 86781b95..e38783ba 100644 --- a/samples/proxy/schema/ProxySchema.cpp +++ b/samples/proxy/schema/ProxySchema.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index 5e4a6ffd..f07ded28 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -106,7 +106,7 @@ std::unique_ptr mock_service() noexcept return result; } -RequestState::RequestState(size_t id) +RequestState::RequestState(std::size_t id) : requestId(id) { } @@ -845,16 +845,16 @@ std::shared_ptr Subscription::getNodeChange(const response::IdType throw std::runtime_error("Unexpected call to getNodeChange"); } -size_t NextAppointmentChange::_notifySubscribeCount = 0; -size_t NextAppointmentChange::_subscriptionCount = 0; -size_t NextAppointmentChange::_notifyUnsubscribeCount = 0; +std::size_t NextAppointmentChange::_notifySubscribeCount = 0; +std::size_t NextAppointmentChange::_subscriptionCount = 0; +std::size_t NextAppointmentChange::_notifyUnsubscribeCount = 0; NextAppointmentChange::NextAppointmentChange(nextAppointmentChange&& changeNextAppointment) : _changeNextAppointment(std::move(changeNextAppointment)) { } -size_t NextAppointmentChange::getCount(service::ResolverContext resolverContext) +std::size_t NextAppointmentChange::getCount(service::ResolverContext resolverContext) { switch (resolverContext) { @@ -963,9 +963,9 @@ std::stack NestedType::getCapturedParams() noexcept std::mutex Expensive::testMutex {}; std::mutex Expensive::pendingExpensiveMutex {}; std::condition_variable Expensive::pendingExpensiveCondition {}; -size_t Expensive::pendingExpensive = 0; +std::size_t Expensive::pendingExpensive = 0; -std::atomic Expensive::instances = 0; +std::atomic Expensive::instances = 0; bool Expensive::Reset() noexcept { diff --git a/samples/today/TodayMock.h b/samples/today/TodayMock.h index 6ed3a3c5..60f97fa1 100644 --- a/samples/today/TodayMock.h +++ b/samples/today/TodayMock.h @@ -34,26 +34,26 @@ const response::IdType& getFakeFolderId() noexcept; struct TodayMockService { std::shared_ptr service {}; - size_t getAppointmentsCount {}; - size_t getTasksCount {}; - size_t getUnreadCountsCount {}; + std::size_t getAppointmentsCount {}; + std::size_t getTasksCount {}; + std::size_t getUnreadCountsCount {}; }; std::unique_ptr mock_service() noexcept; struct RequestState : service::RequestState { - RequestState(size_t id); + RequestState(std::size_t id); - const size_t requestId; + const std::size_t requestId; - size_t appointmentsRequestId = 0; - size_t tasksRequestId = 0; - size_t unreadCountsRequestId = 0; + std::size_t appointmentsRequestId = 0; + std::size_t tasksRequestId = 0; + std::size_t unreadCountsRequestId = 0; - size_t loadAppointmentsCount = 0; - size_t loadTasksCount = 0; - size_t loadUnreadCountsCount = 0; + std::size_t loadAppointmentsCount = 0; + std::size_t loadTasksCount = 0; + std::size_t loadUnreadCountsCount = 0; }; class Appointment; @@ -318,7 +318,7 @@ class NextAppointmentChange explicit NextAppointmentChange(nextAppointmentChange&& changeNextAppointment); - static size_t getCount(service::ResolverContext resolverContext); + static std::size_t getCount(service::ResolverContext resolverContext); std::shared_ptr getNextAppointmentChange( const service::FieldParams& params) const; @@ -327,9 +327,9 @@ class NextAppointmentChange private: nextAppointmentChange _changeNextAppointment; - static size_t _notifySubscribeCount; - static size_t _subscriptionCount; - static size_t _notifyUnsubscribeCount; + static std::size_t _notifySubscribeCount; + static std::size_t _subscriptionCount; + static std::size_t _notifyUnsubscribeCount; }; class NodeChange @@ -388,20 +388,20 @@ class Expensive std::future getOrder(const service::FieldParams& params) const noexcept; - static constexpr size_t count = 5; + static constexpr std::size_t count = 5; static std::mutex testMutex; private: // Block async calls to getOrder until pendingExpensive == count static std::mutex pendingExpensiveMutex; static std::condition_variable pendingExpensiveCondition; - static size_t pendingExpensive; + static std::size_t pendingExpensive; // Number of instances - static std::atomic instances; + static std::atomic instances; // Initialized in the constructor - const size_t order; + const std::size_t order; }; class EmptyOperations : public service::Request diff --git a/samples/today/benchmark.cpp b/samples/today/benchmark.cpp index 20c4bde1..dff6e9c8 100644 --- a/samples/today/benchmark.cpp +++ b/samples/today/benchmark.cpp @@ -18,7 +18,7 @@ using namespace graphql; using namespace std::literals; void outputOverview( - size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept + std::size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept { const auto requestsPerSecond = ((static_cast(iterations) @@ -61,14 +61,14 @@ void outputSegment( int main(int argc, char** argv) { - const size_t iterations = [](const char* arg) noexcept -> size_t { + const std::size_t iterations = [](const char* arg) noexcept -> std::size_t { if (arg) { const int parsed = std::atoi(arg); if (parsed > 0) { - return static_cast(parsed); + return static_cast(parsed); } } @@ -88,7 +88,7 @@ int main(int argc, char** argv) try { - for (size_t i = 0; i < iterations; ++i) + for (std::size_t i = 0; i < iterations; ++i) { const auto startParse = std::chrono::steady_clock::now(); auto query = peg::parseString(R"gql(query { diff --git a/samples/today/nointrospection/TodaySchema.cpp b/samples/today/nointrospection/TodaySchema.cpp index aee07aac..4dd8886a 100644 --- a/samples/today/nointrospection/TodaySchema.cpp +++ b/samples/today/nointrospection/TodaySchema.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -56,7 +57,7 @@ service::AwaitableResolver Result::convert(service::AwaitableS { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); + resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); return resolvedResult; }); @@ -802,10 +803,10 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(Expensive)gql"sv, typeExpensive); typeTaskState->AddEnumValues({ - { service::s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, - { service::s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } + { service::s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, + { service::s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, + { service::s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, + { service::s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } }); typeCompleteTaskInput->AddInputValues({ diff --git a/samples/today/schema/TodaySchema.cpp b/samples/today/schema/TodaySchema.cpp index d11e9e23..27cd44ce 100644 --- a/samples/today/schema/TodaySchema.cpp +++ b/samples/today/schema/TodaySchema.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -56,7 +57,7 @@ service::AwaitableResolver Result::convert(service::AwaitableS { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); + resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); return resolvedResult; }); @@ -805,10 +806,10 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(Expensive)gql"sv, typeExpensive); typeTaskState->AddEnumValues({ - { service::s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, - { service::s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } + { service::s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, + { service::s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, + { service::s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, + { service::s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } }); typeCompleteTaskInput->AddInputValues({ diff --git a/samples/validation/schema/ValidationSchema.cpp b/samples/validation/schema/ValidationSchema.cpp index 9a49b7e7..40410c97 100644 --- a/samples/validation/schema/ValidationSchema.cpp +++ b/samples/validation/schema/ValidationSchema.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -56,7 +57,7 @@ service::AwaitableResolver Result::convert(service::Awai { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesDogCommand[static_cast(value)] }); + resolvedResult.set(std::string { s_namesDogCommand[static_cast(value)] }); return resolvedResult; }); @@ -112,7 +113,7 @@ service::AwaitableResolver Result::convert(service::Awai { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesCatCommand[static_cast(value)] }); + resolvedResult.set(std::string { s_namesCatCommand[static_cast(value)] }); return resolvedResult; }); @@ -258,12 +259,12 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(Arguments)gql"sv, typeArguments); typeDogCommand->AddEnumValues({ - { service::s_namesDogCommand[static_cast(validation::DogCommand::SIT)], R"md()md"sv, std::nullopt }, - { service::s_namesDogCommand[static_cast(validation::DogCommand::DOWN)], R"md()md"sv, std::nullopt }, - { service::s_namesDogCommand[static_cast(validation::DogCommand::HEEL)], R"md()md"sv, std::nullopt } + { service::s_namesDogCommand[static_cast(validation::DogCommand::SIT)], R"md()md"sv, std::nullopt }, + { service::s_namesDogCommand[static_cast(validation::DogCommand::DOWN)], R"md()md"sv, std::nullopt }, + { service::s_namesDogCommand[static_cast(validation::DogCommand::HEEL)], R"md()md"sv, std::nullopt } }); typeCatCommand->AddEnumValues({ - { service::s_namesCatCommand[static_cast(validation::CatCommand::JUMP)], R"md()md"sv, std::nullopt } + { service::s_namesCatCommand[static_cast(validation::CatCommand::JUMP)], R"md()md"sv, std::nullopt } }); typeComplexInput->AddInputValues({ diff --git a/src/Base64.cpp b/src/Base64.cpp index 94e571f5..b40bc6ee 100644 --- a/src/Base64.cpp +++ b/src/Base64.cpp @@ -4,6 +4,7 @@ #include "graphqlservice/internal/Base64.h" #include +#include #include namespace graphql::internal { @@ -111,7 +112,7 @@ std::string Base64::toBase64(const std::vector& bytes) return result; } - size_t count = bytes.size(); + std::size_t count = bytes.size(); const std::uint8_t* data = bytes.data(); result.reserve((count + (count % 3)) * 4 / 3); diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 1a747ec5..da7802ac 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -21,6 +21,7 @@ #endif // _MSC_VER #include +#include #include #include #include @@ -531,7 +532,7 @@ void Generator::outputGetOperationNameDeclaration(std::ostream& headerFile) cons } bool Generator::outputResponseFieldType(std::ostream& headerFile, - const ResponseField& responseField, size_t indent /* = 0 */) const noexcept + const ResponseField& responseField, std::size_t indent /* = 0 */) const noexcept { switch (responseField.type->kind()) { @@ -617,6 +618,7 @@ bool Generator::outputSource() const noexcept #include #include +#include #include #include #include @@ -846,7 +848,7 @@ response::Value Variable<)cpp" response::Value result { response::Type::EnumValue }; - result.set(std::string { s_names[static_cast(value)] }); + result.set(std::string { s_names[static_cast(value)] }); return result; } @@ -1448,9 +1450,9 @@ int main(int argc, char** argv) for (const auto& segment : error.path) { - if (std::holds_alternative(segment)) + if (std::holds_alternative(segment)) { - std::cerr << '[' << std::get(segment) << ']'; + std::cerr << '[' << std::get(segment) << ']'; } else { diff --git a/src/GraphQLClient.cpp b/src/GraphQLClient.cpp index df616f21..f56b0a24 100644 --- a/src/GraphQLClient.cpp +++ b/src/GraphQLClient.cpp @@ -3,6 +3,8 @@ #include "graphqlservice/GraphQLClient.h" +#include + using namespace std::literals; namespace graphql::client { @@ -21,7 +23,7 @@ ErrorLocation parseServiceErrorLocation(response::Value&& location) { if (member.second.type() == response::Type::Int) { - result.line = static_cast(member.second.get()); + result.line = static_cast(member.second.get()); } continue; @@ -31,7 +33,7 @@ ErrorLocation parseServiceErrorLocation(response::Value&& location) { if (member.second.type() == response::Type::Int) { - result.column = static_cast(member.second.get()); + result.column = static_cast(member.second.get()); } continue; diff --git a/src/GraphQLResponse.cpp b/src/GraphQLResponse.cpp index 4036d628..14e958e0 100644 --- a/src/GraphQLResponse.cpp +++ b/src/GraphQLResponse.cpp @@ -6,6 +6,7 @@ #include "graphqlservice/internal/Base64.h" #include +#include #include #include #include @@ -31,7 +32,7 @@ IdType::~IdType() // omitted, declare it explicitly and define it in graphqlresponse. } -IdType::IdType(size_t count, typename ByteData::value_type value /* = 0 */) +IdType::IdType(std::size_t count, typename ByteData::value_type value /* = 0 */) : _data { ByteData(count, value) } { } @@ -95,9 +96,9 @@ bool IdType::operator==(const IdType& rhs) const noexcept return (std::holds_alternative(_data) ? internal::Base64::compareBase64(std::get(_data), - std::get(rhs._data)) + std::get(rhs._data)) : internal::Base64::compareBase64(std::get(rhs._data), - std::get(_data))) + std::get(_data))) == internal::Base64::Comparison::EqualTo; } @@ -140,7 +141,7 @@ bool IdType::operator<(const IdType& rhs) const noexcept return (std::holds_alternative(_data) ? (internal::Base64::compareBase64(std::get(_data), std::get(rhs._data)) - < internal::Base64::Comparison::EqualTo) + < internal::Base64::Comparison::EqualTo) : (internal::Base64::compareBase64(std::get(rhs._data), std::get(_data))) > internal::Base64::Comparison::EqualTo); @@ -161,7 +162,7 @@ bool IdType::empty() const noexcept _data); } -size_t IdType::size() const noexcept +std::size_t IdType::size() const noexcept { return std::visit( [](const auto& data) noexcept { @@ -170,7 +171,7 @@ size_t IdType::size() const noexcept _data); } -size_t IdType::max_size() const noexcept +std::size_t IdType::max_size() const noexcept { return std::visit( [](const auto& data) noexcept { @@ -179,7 +180,7 @@ size_t IdType::max_size() const noexcept _data); } -void IdType::reserve(size_t new_cap) +void IdType::reserve(std::size_t new_cap) { std::visit( [new_cap](auto& data) { @@ -188,7 +189,7 @@ void IdType::reserve(size_t new_cap) _data); } -size_t IdType::capacity() const noexcept +std::size_t IdType::capacity() const noexcept { return std::visit( [](const auto& data) noexcept { @@ -215,7 +216,7 @@ void IdType::clear() noexcept _data); } -const std::uint8_t& IdType::at(size_t pos) const +const std::uint8_t& IdType::at(std::size_t pos) const { if (!std::holds_alternative(_data)) { @@ -225,7 +226,7 @@ const std::uint8_t& IdType::at(size_t pos) const return std::get(_data).at(pos); } -std::uint8_t& IdType::at(size_t pos) +std::uint8_t& IdType::at(std::size_t pos) { if (!std::holds_alternative(_data)) { @@ -235,7 +236,7 @@ std::uint8_t& IdType::at(size_t pos) return std::get(_data).at(pos); } -const std::uint8_t& IdType::operator[](size_t pos) const +const std::uint8_t& IdType::operator[](std::size_t pos) const { if (!std::holds_alternative(_data)) { @@ -245,7 +246,7 @@ const std::uint8_t& IdType::operator[](size_t pos) const return std::get(_data)[pos]; } -std::uint8_t& IdType::operator[](size_t pos) +std::uint8_t& IdType::operator[](std::size_t pos) { if (!std::holds_alternative(_data)) { @@ -1003,7 +1004,7 @@ Value::Value(const Value& other) copy.map.push_back({ entry.first, Value { entry.second } }); } - std::map members; + std::map members; for (const auto& entry : copy.map) { @@ -1027,7 +1028,7 @@ Value::Value(const Value& other) ListType copy {}; copy.reserve(other.size()); - for (size_t i = 0; i < other.size(); ++i) + for (std::size_t i = 0; i < other.size(); ++i) { copy.push_back(Value { other[i] }); } @@ -1090,38 +1091,40 @@ Type Value::typeOf(const TypeData& data) noexcept // As long as the order of the variant alternatives matches the Type enum, we can cast the index // to the Type in one step. static_assert( - std::is_same_v(Type::Map), TypeData>, + std::is_same_v(Type::Map), TypeData>, MapData>, "type mistmatch"); static_assert( - std::is_same_v(Type::List), TypeData>, + std::is_same_v(Type::List), TypeData>, ListType>, "type mistmatch"); static_assert( - std::is_same_v(Type::String), TypeData>, + std::is_same_v(Type::String), TypeData>, StringData>, "type mistmatch"); - static_assert( - std::is_same_v(Type::Boolean), TypeData>, - BooleanType>, + static_assert(std::is_same_v< + std::variant_alternative_t(Type::Boolean), TypeData>, + BooleanType>, "type mistmatch"); static_assert( - std::is_same_v(Type::Int), TypeData>, + std::is_same_v(Type::Int), TypeData>, IntType>, "type mistmatch"); static_assert( - std::is_same_v(Type::Float), TypeData>, + std::is_same_v(Type::Float), TypeData>, FloatType>, "type mistmatch"); static_assert( - std::is_same_v(Type::EnumValue), TypeData>, + std::is_same_v< + std::variant_alternative_t(Type::EnumValue), TypeData>, EnumData>, "type mistmatch"); static_assert( - std::is_same_v(Type::ID), TypeData>, IdType>, + std::is_same_v(Type::ID), TypeData>, + IdType>, "type mistmatch"); static_assert( - std::is_same_v(Type::Scalar), TypeData>, + std::is_same_v(Type::Scalar), TypeData>, ScalarData>, "type mistmatch"); @@ -1270,7 +1273,7 @@ bool Value::maybe_id() const noexcept return false; } -void Value::reserve(size_t count) +void Value::reserve(std::size_t count) { if (std::holds_alternative(_data)) { @@ -1299,7 +1302,7 @@ void Value::reserve(size_t count) } } -size_t Value::size() const +std::size_t Value::size() const { switch (type()) { @@ -1334,7 +1337,7 @@ bool Value::emplace_back(std::string&& name, Value&& value) const auto [itr, itrEnd] = std::equal_range(mapData.members.cbegin(), mapData.members.cend(), std::nullopt, - [&mapData, &name](std::optional lhs, std::optional rhs) noexcept { + [&mapData, &name](std::optional lhs, std::optional rhs) noexcept { std::string_view lhsName { lhs == std::nullopt ? name : mapData.map[*lhs].first }; std::string_view rhsName { rhs == std::nullopt ? name : mapData.map[*rhs].first }; return lhsName < rhsName; @@ -1364,7 +1367,7 @@ MapType::const_iterator Value::find(std::string_view name) const const auto [itr, itrEnd] = std::equal_range(mapData.members.cbegin(), mapData.members.cend(), std::nullopt, - [&mapData, name](std::optional lhs, std::optional rhs) noexcept { + [&mapData, name](std::optional lhs, std::optional rhs) noexcept { std::string_view lhsName { lhs == std::nullopt ? name : mapData.map[*lhs].first }; std::string_view rhsName { rhs == std::nullopt ? name : mapData.map[*rhs].first }; return lhsName < rhsName; @@ -1429,7 +1432,7 @@ void Value::emplace_back(Value&& value) std::get(_data).emplace_back(std::move(value)); } -const Value& Value::operator[](size_t index) const +const Value& Value::operator[](std::size_t index) const { const auto& typeData = data(); diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index d3cd2095..80fe1e62 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -9,6 +9,7 @@ #include #include +#include #include namespace graphql::service { @@ -58,9 +59,10 @@ void addErrorPath(const error_path& path, response::Value& error) errorPath.emplace_back( response::Value { std::string { std::get(segment) } }); } - else if (std::holds_alternative(segment)) + else if (std::holds_alternative(segment)) { - errorPath.emplace_back(response::Value(static_cast(std::get(segment)))); + errorPath.emplace_back( + response::Value(static_cast(std::get(segment)))); } } @@ -250,7 +252,7 @@ void await_worker_queue::resumePending() // Default to immediate synchronous execution. await_async::await_async() : _pimpl { std::static_pointer_cast( - std::make_shared>(std::make_shared())) } + std::make_shared>(std::make_shared())) } { } @@ -258,9 +260,9 @@ await_async::await_async() await_async::await_async(std::launch launch) : _pimpl { ((launch & std::launch::async) == std::launch::async) ? std::static_pointer_cast(std::make_shared>( - std::make_shared())) + std::make_shared())) : std::static_pointer_cast(std::make_shared>( - std::make_shared())) } + std::make_shared())) } { } @@ -885,7 +887,7 @@ class SelectionVisitor public: explicit SelectionVisitor(const SelectionSetParams& selectionSetParams, const FragmentMap& fragments, const response::Value& variables, const TypeNames& typeNames, - const ResolverMap& resolvers, size_t count); + const ResolverMap& resolvers, std::size_t count); void visit(const peg::ast_node& selection); @@ -922,7 +924,7 @@ class SelectionVisitor SelectionVisitor::SelectionVisitor(const SelectionSetParams& selectionSetParams, const FragmentMap& fragments, const response::Value& variables, const TypeNames& typeNames, - const ResolverMap& resolvers, size_t count) + const ResolverMap& resolvers, std::size_t count) : _resolverContext(selectionSetParams.resolverContext) , _state(selectionSetParams.state) , _operationDirectives(selectionSetParams.operationDirectives) @@ -1152,7 +1154,7 @@ void SelectionVisitor::visitFragmentSpread(const peg::ast_node& fragmentSpread) _fragmentDefinitionDirectives->push_front(itr->second.getDirectives()); _fragmentSpreadDirectives->push_front(directiveVisitor.getDirectives()); - const size_t count = itr->second.getSelection().children.size(); + const std::size_t count = itr->second.getSelection().children.size(); if (count > 1) { @@ -1197,7 +1199,7 @@ void SelectionVisitor::visitInlineFragment(const peg::ast_node& inlineFragment) [this, &directiveVisitor](const peg::ast_node& child) { _inlineFragmentDirectives->push_front(directiveVisitor.getDirectives()); - const size_t count = child.children.size(); + const std::size_t count = child.children.size(); if (count > 1) { diff --git a/src/RequestLoader.cpp b/src/RequestLoader.cpp index 4b36020c..44d2a47b 100644 --- a/src/RequestLoader.cpp +++ b/src/RequestLoader.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -162,7 +163,7 @@ std::string RequestLoader::getInputCppType( const RequestSchemaType& inputType, const TypeModifierStack& modifiers) const noexcept { bool nonNull = true; - size_t templateCount = 0; + std::size_t templateCount = 0; std::ostringstream cppType; for (auto modifier : modifiers) @@ -211,7 +212,7 @@ std::string RequestLoader::getInputCppType( cppType << _schemaLoader.getCppType(inputType->name()); - for (size_t i = 0; i < templateCount; ++i) + for (std::size_t i = 0; i < templateCount; ++i) { cppType << R"cpp(>)cpp"; } @@ -223,7 +224,7 @@ std::string RequestLoader::getOutputCppType( std::string_view outputCppType, const TypeModifierStack& modifiers) noexcept { bool nonNull = true; - size_t templateCount = 0; + std::size_t templateCount = 0; std::ostringstream cppType; for (auto modifier : modifiers) @@ -260,7 +261,7 @@ std::string RequestLoader::getOutputCppType( cppType << outputCppType; - for (size_t i = 0; i < templateCount; ++i) + for (std::size_t i = 0; i < templateCount; ++i) { cppType << R"cpp(>)cpp"; } @@ -572,8 +573,7 @@ void RequestLoader::addTypesToSchema() locationValue.set(std::string { locationName }); - return service::Argument::convert( - locationValue); + return service::Argument::convert(locationValue); }); std::vector> arguments( @@ -701,7 +701,8 @@ std::string_view RequestLoader::trimWhitespace(std::string_view content) noexcep if (skip >= 0 && length >= skip) { - content = content.substr(static_cast(skip), static_cast(length - skip)); + content = + content.substr(static_cast(skip), static_cast(length - skip)); } return content; diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 6feaea8d..cd0baf00 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -17,6 +17,7 @@ #endif // _MSC_VER #include +#include #include #include #include @@ -1272,6 +1273,7 @@ bool Generator::outputSource() const noexcept sourceFile << R"cpp( #include #include +#include #include #include #include @@ -1342,7 +1344,7 @@ service::AwaitableResolver Result<)cpp" response::Value resolvedResult(response::Type::EnumValue); resolvedResult.set(std::string { s_names)cpp" - << enumType.cppType << R"cpp([static_cast(value)] }); + << enumType.cppType << R"cpp([static_cast(value)] }); return resolvedResult; }); @@ -1902,9 +1904,9 @@ Operations::Operations()cpp"; firstValue = false; sourceFile << R"cpp( { service::s_names)cpp" << enumType.cppType - << R"cpp([static_cast()cpp" << _loader.getSchemaNamespace() - << R"cpp(::)cpp" << enumType.cppType << R"cpp(::)cpp" - << enumValue.cppValue << R"cpp()], R"md()cpp"; + << R"cpp([static_cast()cpp" + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType + << R"cpp(::)cpp" << enumValue.cppValue << R"cpp()], R"md()cpp"; if (!_options.noIntrospection) { @@ -2087,8 +2089,7 @@ Operations::Operations()cpp"; )cpp"; } sourceFile << R"cpp(}, )cpp" - << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") - << R"cpp()); + << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") << R"cpp()); )cpp"; } } @@ -2646,7 +2647,7 @@ void Generator::outputIntrospectionFields( } std::string Generator::getArgumentDefaultValue( - size_t level, const response::Value& defaultValue) const noexcept + std::size_t level, const response::Value& defaultValue) const noexcept { const std::string padding(level, '\t'); std::ostringstream argumentDefaultValue; @@ -2933,7 +2934,7 @@ std::string Generator::getTypeModifiers(const TypeModifierStack& modifiers) cons std::string Generator::getIntrospectionType( std::string_view type, const TypeModifierStack& modifiers) const noexcept { - size_t wrapperCount = 0; + std::size_t wrapperCount = 0; bool nonNull = true; std::ostringstream introspectionType; @@ -2995,7 +2996,7 @@ std::string Generator::getIntrospectionType( introspectionType << R"cpp(schema->LookupType(R"gql()cpp" << type << R"cpp()gql"sv))cpp"; - for (size_t i = 0; i < wrapperCount; ++i) + for (std::size_t i = 0; i < wrapperCount; ++i) { introspectionType << R"cpp())cpp"; } diff --git a/src/SchemaLoader.cpp b/src/SchemaLoader.cpp index 9129ec48..3e0827a8 100644 --- a/src/SchemaLoader.cpp +++ b/src/SchemaLoader.cpp @@ -4,6 +4,7 @@ #include "SchemaLoader.h" #include +#include #include #include #include @@ -1614,7 +1615,7 @@ const tao::graphqlpeg::position& SchemaLoader::getTypePosition(std::string_view return _typePositions.at(type); } -size_t SchemaLoader::getScalarIndex(std::string_view type) const +std::size_t SchemaLoader::getScalarIndex(std::string_view type) const { return _scalarNames.at(type); } @@ -1624,7 +1625,7 @@ const ScalarTypeList& SchemaLoader::getScalarTypes() const noexcept return _scalarTypes; } -size_t SchemaLoader::getEnumIndex(std::string_view type) const +std::size_t SchemaLoader::getEnumIndex(std::string_view type) const { return _enumNames.at(type); } @@ -1634,7 +1635,7 @@ const EnumTypeList& SchemaLoader::getEnumTypes() const noexcept return _enumTypes; } -size_t SchemaLoader::getInputIndex(std::string_view type) const +std::size_t SchemaLoader::getInputIndex(std::string_view type) const { return _inputNames.at(type); } @@ -1644,7 +1645,7 @@ const InputTypeList& SchemaLoader::getInputTypes() const noexcept return _inputTypes; } -size_t SchemaLoader::getUnionIndex(std::string_view type) const +std::size_t SchemaLoader::getUnionIndex(std::string_view type) const { return _unionNames.at(type); } @@ -1654,7 +1655,7 @@ const UnionTypeList& SchemaLoader::getUnionTypes() const noexcept return _unionTypes; } -size_t SchemaLoader::getInterfaceIndex(std::string_view type) const +std::size_t SchemaLoader::getInterfaceIndex(std::string_view type) const { return _interfaceNames.at(type); } @@ -1664,7 +1665,7 @@ const InterfaceTypeList& SchemaLoader::getInterfaceTypes() const noexcept return _interfaceTypes; } -size_t SchemaLoader::getObjectIndex(std::string_view type) const +std::size_t SchemaLoader::getObjectIndex(std::string_view type) const { return _objectNames.at(type); } @@ -1695,9 +1696,9 @@ std::string_view SchemaLoader::getCppType(std::string_view type) const noexcept if (itrBuiltin != s_builtinTypes.cend()) { - if (static_cast(itrBuiltin->second) < s_builtinCppTypes.size()) + if (static_cast(itrBuiltin->second) < s_builtinCppTypes.size()) { - return s_builtinCppTypes[static_cast(itrBuiltin->second)]; + return s_builtinCppTypes[static_cast(itrBuiltin->second)]; } } else @@ -1716,7 +1717,7 @@ std::string_view SchemaLoader::getCppType(std::string_view type) const noexcept std::string SchemaLoader::getInputCppType(const InputField& field) const noexcept { bool nonNull = true; - size_t templateCount = 0; + std::size_t templateCount = 0; std::ostringstream inputType; for (auto modifier : field.modifiers) @@ -1765,7 +1766,7 @@ std::string SchemaLoader::getInputCppType(const InputField& field) const noexcep inputType << getCppType(field.type); - for (size_t i = 0; i < templateCount; ++i) + for (std::size_t i = 0; i < templateCount; ++i) { inputType << R"cpp(>)cpp"; } @@ -1776,7 +1777,7 @@ std::string SchemaLoader::getInputCppType(const InputField& field) const noexcep std::string SchemaLoader::getOutputCppType(const OutputField& field) const noexcept { bool nonNull = true; - size_t templateCount = 0; + std::size_t templateCount = 0; std::ostringstream outputType; switch (field.fieldType) @@ -1855,7 +1856,7 @@ std::string SchemaLoader::getOutputCppType(const OutputField& field) const noexc break; } - for (size_t i = 0; i < templateCount; ++i) + for (std::size_t i = 0; i < templateCount; ++i) { outputType << R"cpp(>)cpp"; } diff --git a/src/SyntaxTree.cpp b/src/SyntaxTree.cpp index 60743538..b0882ac1 100644 --- a/src/SyntaxTree.cpp +++ b/src/SyntaxTree.cpp @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -50,14 +51,14 @@ std::string_view ast_node::unescaped_view() const && child->children.front()->is_type() && child->children.back()->is_type()) ? std::make_optional(std::make_pair(child->children.front()->string_view(), - child->children.back()->unescaped_view())) + child->children.back()->unescaped_view())) : std::nullopt; }); // Calculate the common indent const auto commonIndent = std::accumulate(lines.cbegin(), lines.cend(), - std::optional {}, + std::optional {}, [](auto value, const auto& line) noexcept { if (line) { @@ -79,7 +80,7 @@ std::string_view ast_node::unescaped_view() const { joined.reserve(std::accumulate(lines.cbegin(), lines.cend(), - size_t {}, + std::size_t {}, [trimIndent](auto value, const auto& line) noexcept { if (line) { @@ -118,8 +119,8 @@ std::string_view ast_node::unescaped_view() const joined.reserve(std::accumulate(children.cbegin(), children.cend(), - size_t(0), - [](size_t total, const std::unique_ptr& child) { + std::size_t(0), + [](std::size_t total, const std::unique_ptr& child) { return total + child->string_view().size(); })); @@ -642,7 +643,7 @@ struct ast_action : nothing struct [[nodiscard("unnecessary construction")]] depth_guard { - explicit depth_guard(size_t & depth) noexcept + explicit depth_guard(std::size_t& depth) noexcept : _depth(depth) { ++_depth; @@ -653,14 +654,14 @@ struct [[nodiscard("unnecessary construction")]] depth_guard --_depth; } - depth_guard(depth_guard &&) noexcept = delete; + depth_guard(depth_guard&&) noexcept = delete; depth_guard(const depth_guard&) = delete; depth_guard& operator=(depth_guard&&) noexcept = delete; depth_guard& operator=(const depth_guard&) = delete; private: - size_t& _depth; + std::size_t& _depth; }; template <> @@ -981,21 +982,21 @@ class [[nodiscard("unnecessary construction")]] depth_limit_input : public Parse { public: template - explicit depth_limit_input(size_t depthLimit, Args && ... args) noexcept + explicit depth_limit_input(std::size_t depthLimit, Args&&... args) noexcept : ParseInput(std::forward(args)...) , _depthLimit(depthLimit) { } - size_t depthLimit() const noexcept + std::size_t depthLimit() const noexcept { return _depthLimit; } - size_t selectionSetDepth = 0; + std::size_t selectionSetDepth = 0; private: - const size_t _depthLimit; + const std::size_t _depthLimit; }; using ast_file = depth_limit_input>; @@ -1018,7 +1019,7 @@ struct [[nodiscard("unnecessary construction")]] ast_input std::variant, ast_string_view> data; }; -ast parseSchemaString(std::string_view input, size_t depthLimit) +ast parseSchemaString(std::string_view input, std::size_t depthLimit) { ast result { std::make_shared( ast_input { ast_string { { input.cbegin(), input.cend() } } }), @@ -1050,7 +1051,7 @@ ast parseSchemaString(std::string_view input, size_t depthLimit) return result; } -ast parseSchemaFile(std::string_view filename, size_t depthLimit) +ast parseSchemaFile(std::string_view filename, std::size_t depthLimit) { ast result; @@ -1081,7 +1082,7 @@ ast parseSchemaFile(std::string_view filename, size_t depthLimit) return result; } -ast parseString(std::string_view input, size_t depthLimit) +ast parseString(std::string_view input, std::size_t depthLimit) { ast result { std::make_shared( ast_input { ast_string { { input.cbegin(), input.cend() } } }), @@ -1114,7 +1115,7 @@ ast parseString(std::string_view input, size_t depthLimit) return result; } -ast parseFile(std::string_view filename, size_t depthLimit) +ast parseFile(std::string_view filename, std::size_t depthLimit) { ast result; @@ -1148,7 +1149,7 @@ ast parseFile(std::string_view filename, size_t depthLimit) } // namespace peg -peg::ast operator"" _graphql(const char* text, size_t size) +peg::ast operator"" _graphql(const char* text, std::size_t size) { peg::ast result { std::make_shared( peg::ast_input { peg::ast_string_view { { text, size } } }), diff --git a/src/Validation.cpp b/src/Validation.cpp index a95c8624..9ed417e1 100644 --- a/src/Validation.cpp +++ b/src/Validation.cpp @@ -9,6 +9,7 @@ #include "graphqlservice/introspection/IntrospectionSchema.h" #include +#include #include #include #include @@ -1770,7 +1771,7 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) selection = &child; }); - size_t subFieldCount = 0; + std::size_t subFieldCount = 0; if (selection != nullptr) { diff --git a/src/introspection/IntrospectionSchema.cpp b/src/introspection/IntrospectionSchema.cpp index 81b28bf4..048cbcc9 100644 --- a/src/introspection/IntrospectionSchema.cpp +++ b/src/introspection/IntrospectionSchema.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -50,7 +51,7 @@ service::AwaitableResolver Result::convert(service::Awa { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesTypeKind[static_cast(value)] }); + resolvedResult.set(std::string { s_namesTypeKind[static_cast(value)] }); return resolvedResult; }); @@ -106,7 +107,7 @@ service::AwaitableResolver Result::convert(ser { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesDirectiveLocation[static_cast(value)] }); + resolvedResult.set(std::string { s_namesDirectiveLocation[static_cast(value)] }); return resolvedResult; }); @@ -160,35 +161,35 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(__Directive)gql"sv, typeDirective); typeTypeKind->AddEnumValues({ - { service::s_namesTypeKind[static_cast(introspection::TypeKind::SCALAR)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::INTERFACE)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::UNION)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::ENUM)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::LIST)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::NON_NULL)], R"md()md"sv, std::nullopt } + { service::s_namesTypeKind[static_cast(introspection::TypeKind::SCALAR)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::OBJECT)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::INTERFACE)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::UNION)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::ENUM)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::LIST)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::NON_NULL)], R"md()md"sv, std::nullopt } }); typeDirectiveLocation->AddEnumValues({ - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::QUERY)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::MUTATION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SUBSCRIPTION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_SPREAD)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INLINE_FRAGMENT)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::VARIABLE_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCHEMA)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCALAR)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ARGUMENT_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INTERFACE)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::UNION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM_VALUE)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_FIELD_DEFINITION)], R"md()md"sv, std::nullopt } + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::QUERY)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::MUTATION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SUBSCRIPTION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_DEFINITION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_SPREAD)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INLINE_FRAGMENT)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::VARIABLE_DEFINITION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCHEMA)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCALAR)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::OBJECT)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD_DEFINITION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ARGUMENT_DEFINITION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INTERFACE)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::UNION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM_VALUE)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_FIELD_DEFINITION)], R"md()md"sv, std::nullopt } }); AddSchemaDetails(typeSchema, schema); diff --git a/test/ArgumentTests.cpp b/test/ArgumentTests.cpp index aa255700..557d4e71 100644 --- a/test/ArgumentTests.cpp +++ b/test/ArgumentTests.cpp @@ -7,6 +7,8 @@ #include "graphqlservice/JSONResponse.h" +#include + using namespace graphql; TEST(ArgumentsCase, ListArgumentStrings) @@ -27,7 +29,7 @@ TEST(ArgumentsCase, ListArgumentStrings) FAIL() << response::toJSON(ex.getErrors()); } - ASSERT_EQ(size_t { 3 }, actual.size()) << "should get 3 entries"; + ASSERT_EQ(std::size_t { 3 }, actual.size()) << "should get 3 entries"; EXPECT_EQ("string1", actual[0]) << "entry should match"; EXPECT_EQ("string2", actual[1]) << "entry should match"; EXPECT_EQ("string3", actual[2]) << "entry should match"; @@ -80,7 +82,7 @@ TEST(ArgumentsCase, ListArgumentStringsNullable) FAIL() << response::toJSON(ex.getErrors()); } - ASSERT_EQ(size_t { 4 }, actual.size()) << "should get 4 entries"; + ASSERT_EQ(std::size_t { 4 }, actual.size()) << "should get 4 entries"; ASSERT_TRUE(actual[0].has_value()) << "should not be null"; EXPECT_EQ("string1", *actual[0]) << "entry should match"; ASSERT_TRUE(actual[1].has_value()) << "should not be null"; @@ -108,11 +110,11 @@ TEST(ArgumentsCase, ListArgumentListArgumentStrings) FAIL() << response::toJSON(ex.getErrors()); } - ASSERT_EQ(size_t { 2 }, actual.size()) << "should get 2 entries"; - ASSERT_EQ(size_t { 2 }, actual[0].size()) << "should get 2 entries"; + ASSERT_EQ(std::size_t { 2 }, actual.size()) << "should get 2 entries"; + ASSERT_EQ(std::size_t { 2 }, actual[0].size()) << "should get 2 entries"; EXPECT_EQ("list1string1", actual[0][0]) << "entry should match"; EXPECT_EQ("list1string2", actual[0][1]) << "entry should match"; - ASSERT_EQ(size_t { 2 }, actual[1].size()) << "should get 2 entries"; + ASSERT_EQ(std::size_t { 2 }, actual[1].size()) << "should get 2 entries"; EXPECT_EQ("list2string1", actual[1][0]) << "entry should match"; EXPECT_EQ("list2string2", actual[1][1]) << "entry should match"; } @@ -136,9 +138,9 @@ TEST(ArgumentsCase, ListArgumentNullableListArgumentStrings) FAIL() << response::toJSON(ex.getErrors()); } - ASSERT_EQ(size_t { 2 }, actual.size()) << "should get 2 entries"; + ASSERT_EQ(std::size_t { 2 }, actual.size()) << "should get 2 entries"; EXPECT_FALSE(actual[0].has_value()) << "should be null"; - ASSERT_EQ(size_t { 2 }, actual[1]->size()) << "should get 2 entries"; + ASSERT_EQ(std::size_t { 2 }, actual[1]->size()) << "should get 2 entries"; EXPECT_EQ("list2string1", (*actual[1])[0]) << "entry should match"; EXPECT_EQ("list2string2", (*actual[1])[1]) << "entry should match"; } @@ -241,7 +243,7 @@ TEST(ArgumentsCase, ScalarArgumentMap) ASSERT_EQ(response::Type::Map, actual.type()) << "should parse the object"; values = actual.release(); - ASSERT_EQ(size_t { 1 }, values.size()) << "should have a single key/value"; + ASSERT_EQ(std::size_t { 1 }, values.size()) << "should have a single key/value"; ASSERT_EQ("foo", values.front().first) << "should match the key"; ASSERT_EQ("bar", values.front().second.get()) << "should match the value"; } @@ -264,7 +266,7 @@ TEST(ArgumentsCase, ScalarArgumentList) ASSERT_EQ(response::Type::List, actual.type()) << "should parse the array"; values = actual.release(); - ASSERT_EQ(size_t { 2 }, values.size()) << "should have 2 values"; + ASSERT_EQ(std::size_t { 2 }, values.size()) << "should have 2 values"; ASSERT_EQ("foo", values.front().get()) << "should match the value"; ASSERT_EQ("bar", values.back().get()) << "should match the value"; } diff --git a/test/ClientTests.cpp b/test/ClientTests.cpp index 99835f32..0294c00d 100644 --- a/test/ClientTests.cpp +++ b/test/ClientTests.cpp @@ -9,6 +9,7 @@ #include "TodayMock.h" #include +#include using namespace graphql; @@ -42,20 +43,23 @@ TEST_F(ClientCase, QueryEverything) auto result = _mockService->service ->resolve({ query, {}, std::move(variables), std::launch::async, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 1 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->unreadCountsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -63,10 +67,10 @@ TEST_F(ClientCase, QueryEverything) auto serviceResponse = client::parseServiceResponse(std::move(result)); const auto response = parseResponse(std::move(serviceResponse.data)); - EXPECT_EQ(size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; + EXPECT_EQ(std::size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; ASSERT_TRUE(response.appointments.edges.has_value()) << "appointments should be set"; - ASSERT_EQ(size_t { 1 }, response.appointments.edges->size()) + ASSERT_EQ(std::size_t { 1 }, response.appointments.edges->size()) << "appointments should have 1 entry"; ASSERT_TRUE((*response.appointments.edges)[0].has_value()) << "edge should be set"; const auto& appointmentNode = (*response.appointments.edges)[0]->node; @@ -81,7 +85,7 @@ TEST_F(ClientCase, QueryEverything) EXPECT_EQ("Appointment", appointmentNode->_typename) << "__typename should match"; ASSERT_TRUE(response.tasks.edges.has_value()) << "tasks should be set"; - ASSERT_EQ(size_t { 1 }, response.tasks.edges->size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, response.tasks.edges->size()) << "tasks should have 1 entry"; ASSERT_TRUE((*response.tasks.edges)[0].has_value()) << "edge should be set"; const auto& taskNode = (*response.tasks.edges)[0]->node; ASSERT_TRUE(taskNode.has_value()) << "node should be set"; @@ -92,7 +96,7 @@ TEST_F(ClientCase, QueryEverything) EXPECT_EQ("Task", taskNode->_typename) << "__typename should match"; ASSERT_TRUE(response.unreadCounts.edges.has_value()) << "unreadCounts should be set"; - ASSERT_EQ(size_t { 1 }, response.unreadCounts.edges->size()) + ASSERT_EQ(std::size_t { 1 }, response.unreadCounts.edges->size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE((*response.unreadCounts.edges)[0].has_value()) << "edge should be set"; const auto& unreadCountNode = (*response.unreadCounts.edges)[0]->node; @@ -107,7 +111,7 @@ TEST_F(ClientCase, QueryEverything) EXPECT_EQ(client::query::Query::TaskState::Unassigned, response.testTaskState) << "testTaskState should match"; - ASSERT_EQ(size_t { 1 }, response.anyType.size()) << "anyType should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, response.anyType.size()) << "anyType should have 1 entry"; ASSERT_TRUE(response.anyType[0].has_value()) << "appointment should be set"; const auto& anyType = *response.anyType[0]; EXPECT_EQ("Appointment", anyType._typename) << "__typename should match"; @@ -148,7 +152,7 @@ TEST_F(ClientCase, MutateCompleteTask) auto serviceResponse = client::parseServiceResponse(std::move(result)); const auto response = parseResponse(std::move(serviceResponse.data)); - EXPECT_EQ(size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; + EXPECT_EQ(std::size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; const auto& completedTask = response.completedTask; const auto& task = completedTask.completedTask; @@ -197,7 +201,7 @@ TEST_F(ClientCase, SubscribeNextAppointmentChangeDefault) auto serviceResponse = client::parseServiceResponse(std::move(result)); const auto response = parseResponse(std::move(serviceResponse.data)); - EXPECT_EQ(size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; + EXPECT_EQ(std::size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; const auto& appointmentNode = response.nextAppointment; ASSERT_TRUE(appointmentNode.has_value()) << "should get back a task"; diff --git a/test/CoroutineTests.cpp b/test/CoroutineTests.cpp index 5cf074f8..e78050ab 100644 --- a/test/CoroutineTests.cpp +++ b/test/CoroutineTests.cpp @@ -7,6 +7,8 @@ #include "graphqlservice/JSONResponse.h" +#include + using namespace graphql; using namespace std::literals; @@ -74,20 +76,23 @@ TEST_F(CoroutineCase, QueryEverythingSync) service::await_async { worker }, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 1 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->appointmentsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->unreadCountsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -102,7 +107,7 @@ TEST_F(CoroutineCase, QueryEverythingSync) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -121,7 +126,7 @@ TEST_F(CoroutineCase, QueryEverythingSync) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("id", taskNode)) @@ -136,7 +141,7 @@ TEST_F(CoroutineCase, QueryEverythingSync) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); @@ -201,20 +206,23 @@ TEST_F(CoroutineCase, QueryEverythingQueued) service::await_async { worker }, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 2 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 2 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 2 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 2 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 2 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 2 }, state->unreadCountsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -229,7 +237,7 @@ TEST_F(CoroutineCase, QueryEverythingQueued) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -248,7 +256,7 @@ TEST_F(CoroutineCase, QueryEverythingQueued) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("id", taskNode)) @@ -263,7 +271,7 @@ TEST_F(CoroutineCase, QueryEverythingQueued) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); @@ -328,20 +336,23 @@ TEST_F(CoroutineCase, QueryEverythingThreaded) service::await_async { worker }, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 3 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 3 }, state->appointmentsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 3 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 3 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 3 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 3 }, state->unreadCountsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -356,7 +367,7 @@ TEST_F(CoroutineCase, QueryEverythingThreaded) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -375,7 +386,7 @@ TEST_F(CoroutineCase, QueryEverythingThreaded) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("id", taskNode)) @@ -390,7 +401,7 @@ TEST_F(CoroutineCase, QueryEverythingThreaded) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); diff --git a/test/NoIntrospectionTests.cpp b/test/NoIntrospectionTests.cpp index 371e807f..2fc72754 100644 --- a/test/NoIntrospectionTests.cpp +++ b/test/NoIntrospectionTests.cpp @@ -8,6 +8,7 @@ #include "graphqlservice/JSONResponse.h" #include +#include using namespace graphql; @@ -75,20 +76,23 @@ TEST_F(NoIntrospectionServiceCase, QueryEverything) _mockService->service ->resolve({ query, "Everything"sv, std::move(variables), std::launch::async, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 1 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->unreadCountsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -103,7 +107,7 @@ TEST_F(NoIntrospectionServiceCase, QueryEverything) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -122,7 +126,7 @@ TEST_F(NoIntrospectionServiceCase, QueryEverything) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("id", taskNode)) @@ -137,7 +141,7 @@ TEST_F(NoIntrospectionServiceCase, QueryEverything) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); diff --git a/test/PegtlCombinedTests.cpp b/test/PegtlCombinedTests.cpp index 170c751f..a4e54521 100644 --- a/test/PegtlCombinedTests.cpp +++ b/test/PegtlCombinedTests.cpp @@ -7,6 +7,8 @@ #include +#include + using namespace graphql; using namespace graphql::peg; @@ -14,6 +16,6 @@ using namespace tao::graphqlpeg; TEST(PegtlCombinedCase, AnalyzeMixedGrammar) { - ASSERT_EQ(size_t { 0 }, analyze(true)) + ASSERT_EQ(std::size_t { 0 }, analyze(true)) << "there shouldn't be any infinite loops in the PEG version of the grammar"; } diff --git a/test/PegtlExecutableTests.cpp b/test/PegtlExecutableTests.cpp index 4dc47120..af14bd4d 100644 --- a/test/PegtlExecutableTests.cpp +++ b/test/PegtlExecutableTests.cpp @@ -9,6 +9,8 @@ #include +#include + using namespace graphql; using namespace graphql::peg; @@ -138,7 +140,7 @@ TEST(PegtlExecutableCase, ParseVariableDefaultEmptyList) TEST(PegtlExecutableCase, AnalyzeExecutableGrammar) { - ASSERT_EQ(size_t { 0 }, analyze(true)) + ASSERT_EQ(std::size_t { 0 }, analyze(true)) << "there shouldn't be any infinite loops in the PEG version of the grammar"; } @@ -248,8 +250,7 @@ TEST(PegtlExecutableCase, ParseFloatWithFractionalAndExponentialParts) TEST(PegtlExecutableCase, ParseIgnoreUnicodeBOM) { - memory_input<> input("query { \xEF\xBB\xBF __typename }", - "ParseIgnoreUnicodeBOM"); + memory_input<> input("query { \xEF\xBB\xBF __typename }", "ParseIgnoreUnicodeBOM"); const bool result = parse(input); diff --git a/test/PegtlSchemaTests.cpp b/test/PegtlSchemaTests.cpp index 330a6d72..24e621fd 100644 --- a/test/PegtlSchemaTests.cpp +++ b/test/PegtlSchemaTests.cpp @@ -7,6 +7,8 @@ #include +#include + using namespace graphql; using namespace graphql::peg; @@ -219,6 +221,6 @@ TEST(PegtlSchemaCase, ParseTodaySchema) TEST(PegtlSchemaCase, AnalyzeSchemaGrammar) { - ASSERT_EQ(size_t { 0 }, analyze(true)) + ASSERT_EQ(std::size_t { 0 }, analyze(true)) << "there shouldn't be any infinite loops in the PEG version of the grammar"; } diff --git a/test/TodayTests.cpp b/test/TodayTests.cpp index 95ed9414..c38852ea 100644 --- a/test/TodayTests.cpp +++ b/test/TodayTests.cpp @@ -8,6 +8,7 @@ #include "graphqlservice/JSONResponse.h" #include +#include using namespace graphql; @@ -72,20 +73,23 @@ TEST_F(TodayServiceCase, QueryEverything) _mockService->service ->resolve({ query, "Everything"sv, std::move(variables), std::launch::async, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 1 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->unreadCountsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -100,7 +104,7 @@ TEST_F(TodayServiceCase, QueryEverything) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -119,7 +123,7 @@ TEST_F(TodayServiceCase, QueryEverything) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("id", taskNode)) @@ -134,7 +138,7 @@ TEST_F(TodayServiceCase, QueryEverything) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); @@ -171,20 +175,21 @@ TEST_F(TodayServiceCase, QueryAppointments) auto state = std::make_shared(2); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 2 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 2 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -200,7 +205,7 @@ TEST_F(TodayServiceCase, QueryAppointments) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -239,20 +244,21 @@ TEST_F(TodayServiceCase, QueryAppointmentsWithForceError) auto state = std::make_shared(2); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 2 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 2 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -275,7 +281,7 @@ TEST_F(TodayServiceCase, QueryAppointmentsWithForceError) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -315,20 +321,21 @@ TEST_F(TodayServiceCase, QueryAppointmentsWithForceErrorAsync) auto result = _mockService->service ->resolve({ query, {}, std::move(variables), std::launch::async, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 2 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 2 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -351,7 +358,7 @@ TEST_F(TodayServiceCase, QueryAppointmentsWithForceErrorAsync) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -388,21 +395,22 @@ TEST_F(TodayServiceCase, QueryTasks) auto state = std::make_shared(3); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_GE(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 0 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->appointmentsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 3 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 3 }, state->tasksRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadAppointmentsCount) + EXPECT_EQ(std::size_t { 0 }, state->loadAppointmentsCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -418,7 +426,7 @@ TEST_F(TodayServiceCase, QueryTasks) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("taskId", taskNode)) @@ -451,21 +459,22 @@ TEST_F(TodayServiceCase, QueryUnreadCounts) auto state = std::make_shared(4); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_GE(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 0 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->appointmentsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 4 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 4 }, state->unreadCountsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->loadAppointmentsCount) + EXPECT_EQ(std::size_t { 0 }, state->loadAppointmentsCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -480,7 +489,7 @@ TEST_F(TodayServiceCase, QueryUnreadCounts) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); @@ -615,7 +624,8 @@ TEST_F(TodayServiceCase, SubscribeNextAppointmentChangeOverride) auto subscriptionObject = std::make_shared( [](const std::shared_ptr& state) -> std::shared_ptr { - EXPECT_EQ(size_t { 7 }, std::static_pointer_cast(state)->requestId) + EXPECT_EQ(std::size_t { 7 }, + std::static_pointer_cast(state)->requestId) << "should pass the RequestState to the subscription resolvers"; return std::make_shared( response::IdType(today::getFakeAppointmentId()), @@ -963,7 +973,7 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) capturedParams.pop(); const auto params1 = std::move(capturedParams.top()); capturedParams.pop(); - ASSERT_EQ(size_t { 1 }, params1.operationDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params1.operationDirectives.size()) << "missing operation directive"; const auto itrQueryTag1 = params1.operationDirectives.cbegin(); ASSERT_TRUE(itrQueryTag1->first == "queryTag"sv) << "missing required directive"; @@ -972,18 +982,19 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto fragmentDefinitionCount1 = params1.fragmentDefinitionDirectives.size(); const auto fragmentSpreadCount1 = params1.fragmentSpreadDirectives.size(); const auto inlineFragmentCount1 = params1.inlineFragmentDirectives.size(); - ASSERT_EQ(size_t { 1 }, params1.fieldDirectives.size()) << "missing operation directive"; + ASSERT_EQ(std::size_t { 1 }, params1.fieldDirectives.size()) + << "missing operation directive"; const auto itrFieldTag1 = params1.fieldDirectives.cbegin(); ASSERT_TRUE(itrFieldTag1->first == "fieldTag"sv) << "missing required directive"; const auto& fieldTag1 = itrFieldTag1->second; const auto field1 = service::StringArgument::require("field", fieldTag1); - ASSERT_EQ(size_t { 1 }, params2.operationDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params2.operationDirectives.size()) << "missing operation directive"; const auto itrQueryTag2 = params2.operationDirectives.cbegin(); ASSERT_TRUE(itrQueryTag2->first == "queryTag"sv) << "missing required directive"; const auto& queryTag2 = itrQueryTag2->second; const auto query2 = service::StringArgument::require("query", queryTag2); - ASSERT_EQ(size_t { 1 }, params2.fragmentDefinitionDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params2.fragmentDefinitionDirectives.size()) << "missing fragment definition directive"; const auto itrFragmentDefinitionTag2 = params2.fragmentDefinitionDirectives.cbegin(); ASSERT_TRUE(itrFragmentDefinitionTag2->first == "fragmentDefinitionTag"sv) @@ -991,7 +1002,7 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto& fragmentDefinitionTag2 = itrFragmentDefinitionTag2->second; const auto fragmentDefinition2 = service::StringArgument::require("fragmentDefinition", fragmentDefinitionTag2); - ASSERT_EQ(size_t { 1 }, params2.fragmentSpreadDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params2.fragmentSpreadDirectives.size()) << "missing fragment spread directive"; const auto itrFragmentSpreadTag2 = params2.fragmentSpreadDirectives.cbegin(); ASSERT_TRUE(itrFragmentSpreadTag2->first == "fragmentSpreadTag"sv) @@ -1000,18 +1011,18 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto fragmentSpread2 = service::StringArgument::require("fragmentSpread", fragmentSpreadTag2); const auto inlineFragmentCount2 = params2.inlineFragmentDirectives.size(); - ASSERT_EQ(size_t { 1 }, params2.fieldDirectives.size()) << "missing field directive"; + ASSERT_EQ(std::size_t { 1 }, params2.fieldDirectives.size()) << "missing field directive"; const auto itrFieldTag2 = params2.fieldDirectives.cbegin(); ASSERT_TRUE(itrFieldTag2->first == "fieldTag"sv) << "missing field directive"; const auto& fieldTag2 = itrFieldTag2->second; const auto field2 = service::StringArgument::require("field", fieldTag2); - ASSERT_EQ(size_t { 1 }, params3.operationDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params3.operationDirectives.size()) << "missing operation directive"; const auto itrQueryTag3 = params3.operationDirectives.cbegin(); ASSERT_TRUE(itrQueryTag3->first == "queryTag"sv) << "missing required directive"; const auto& queryTag3 = itrQueryTag3->second; const auto query3 = service::StringArgument::require("query", queryTag3); - ASSERT_EQ(size_t { 1 }, params3.fragmentDefinitionDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params3.fragmentDefinitionDirectives.size()) << "missing fragment definition directive"; const auto itrFragmentDefinitionTag3 = params3.fragmentDefinitionDirectives.cbegin(); ASSERT_TRUE(itrFragmentDefinitionTag3->first == "fragmentDefinitionTag"sv) @@ -1019,7 +1030,7 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto& fragmentDefinitionTag3 = itrFragmentDefinitionTag3->second; const auto fragmentDefinition3 = service::StringArgument::require("fragmentDefinition", fragmentDefinitionTag3); - ASSERT_EQ(size_t { 1 }, params3.fragmentSpreadDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params3.fragmentSpreadDirectives.size()) << "missing fragment spread directive"; const auto itrFragmentSpreadTag3 = params3.fragmentSpreadDirectives.cbegin(); ASSERT_TRUE(itrFragmentSpreadTag3->first == "fragmentSpreadTag"sv) @@ -1027,19 +1038,19 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto& fragmentSpreadTag3 = itrFragmentSpreadTag3->second; const auto fragmentSpread3 = service::StringArgument::require("fragmentSpread", fragmentSpreadTag3); - ASSERT_EQ(size_t { 1 }, params3.inlineFragmentDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params3.inlineFragmentDirectives.size()) << "missing inline fragment directive"; const auto itrInlineFragmentTag3 = params3.inlineFragmentDirectives.cbegin(); ASSERT_TRUE(itrInlineFragmentTag3->first == "inlineFragmentTag"sv); const auto& inlineFragmentTag3 = itrInlineFragmentTag3->second; const auto inlineFragment3 = service::StringArgument::require("inlineFragment", inlineFragmentTag3); - ASSERT_EQ(size_t { 1 }, params3.fieldDirectives.size()) << "missing field directive"; + ASSERT_EQ(std::size_t { 1 }, params3.fieldDirectives.size()) << "missing field directive"; const auto itrFieldTag3 = params3.fieldDirectives.cbegin(); ASSERT_TRUE(itrFieldTag3->first == "fieldTag"sv) << "missing field directive"; const auto& fieldTag3 = itrFieldTag3->second; const auto field3 = service::StringArgument::require("field", fieldTag3); - ASSERT_EQ(size_t { 1 }, params4.operationDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params4.operationDirectives.size()) << "missing operation directive"; const auto itrQueryTag4 = params4.operationDirectives.cbegin(); ASSERT_TRUE(itrQueryTag4->first == "queryTag"sv) << "missing required directive"; @@ -1047,19 +1058,20 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto query4 = service::StringArgument::require("query", queryTag4); const auto fragmentDefinitionCount4 = params4.fragmentDefinitionDirectives.size(); const auto fragmentSpreadCount4 = params4.fragmentSpreadDirectives.size(); - ASSERT_EQ(size_t { 1 }, params4.inlineFragmentDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params4.inlineFragmentDirectives.size()) << "missing inline fragment directive"; const auto itrInlineFragmentTag4 = params4.inlineFragmentDirectives.cbegin(); ASSERT_TRUE(itrInlineFragmentTag4->first == "inlineFragmentTag"sv); const auto& inlineFragmentTag4 = itrInlineFragmentTag4->second; const auto inlineFragment4 = service::StringArgument::require("inlineFragment", inlineFragmentTag4); - ASSERT_EQ(size_t { 3 }, params4.fieldDirectives.size()) << "missing field directive"; + ASSERT_EQ(std::size_t { 3 }, params4.fieldDirectives.size()) << "missing field directive"; const auto itrRepeatable1 = params4.fieldDirectives.cbegin(); ASSERT_TRUE(itrRepeatable1->first == "repeatableOnField"sv) << "missing field directive"; EXPECT_TRUE(response::Type::Map == itrRepeatable1->second.type()) << "unexpected arguments type directive"; - EXPECT_EQ(size_t { 0 }, itrRepeatable1->second.size()) << "extra arguments on directive"; + EXPECT_EQ(std::size_t { 0 }, itrRepeatable1->second.size()) + << "extra arguments on directive"; const auto itrFieldTag4 = itrRepeatable1 + 1; ASSERT_TRUE(itrFieldTag4->first == "fieldTag"sv) << "missing field directive"; const auto& fieldTag4 = itrFieldTag4->second; @@ -1067,7 +1079,8 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) ASSERT_TRUE(itrRepeatable2->first == "repeatableOnField"sv) << "missing field directive"; EXPECT_TRUE(response::Type::Map == itrRepeatable2->second.type()) << "unexpected arguments type directive"; - EXPECT_EQ(size_t { 0 }, itrRepeatable2->second.size()) << "extra arguments on directive"; + EXPECT_EQ(std::size_t { 0 }, itrRepeatable2->second.size()) + << "extra arguments on directive"; const auto field4 = service::StringArgument::require("field", fieldTag4); ASSERT_EQ(1, depth1); @@ -1076,16 +1089,16 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) ASSERT_EQ(4, depth4); ASSERT_TRUE(capturedParams.empty()); ASSERT_EQ("nested", query1) << "remember the operation directives"; - ASSERT_EQ(size_t { 0 }, fragmentDefinitionCount1); - ASSERT_EQ(size_t { 0 }, fragmentSpreadCount1); - ASSERT_EQ(size_t { 0 }, inlineFragmentCount1); + ASSERT_EQ(std::size_t { 0 }, fragmentDefinitionCount1); + ASSERT_EQ(std::size_t { 0 }, fragmentSpreadCount1); + ASSERT_EQ(std::size_t { 0 }, inlineFragmentCount1); ASSERT_EQ("nested1", field1) << "remember the field directives"; ASSERT_EQ("nested", query2) << "remember the operation directives"; ASSERT_EQ("fragmentDefinition1", fragmentDefinition2) << "remember the directives from the fragment definition"; ASSERT_EQ("fragmentSpread1", fragmentSpread2) << "remember the directives from the fragment spread"; - ASSERT_EQ(size_t { 0 }, inlineFragmentCount2); + ASSERT_EQ(std::size_t { 0 }, inlineFragmentCount2); ASSERT_EQ("nested2", field2) << "remember the field directives"; ASSERT_EQ("nested", query3) << "remember the operation directives"; ASSERT_EQ("fragmentDefinition2", fragmentDefinition3) @@ -1096,10 +1109,10 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) << "remember the directives from the inline fragment"; ASSERT_EQ("nested3", field3) << "remember the field directives"; ASSERT_EQ("nested", query4) << "remember the operation directives"; - ASSERT_EQ(size_t { 0 }, fragmentDefinitionCount4) + ASSERT_EQ(std::size_t { 0 }, fragmentDefinitionCount4) << "traversing a field to a nested object SelectionSet resets the fragment " "directives"; - ASSERT_EQ(size_t { 0 }, fragmentSpreadCount4) + ASSERT_EQ(std::size_t { 0 }, fragmentSpreadCount4) << "traversing a field to a nested object SelectionSet resets the fragment " "directives"; ASSERT_EQ("inlineFragment5", inlineFragment4) @@ -1128,20 +1141,21 @@ TEST_F(TodayServiceCase, QueryAppointmentsById) auto state = std::make_shared(12); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 12 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 12 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -1156,7 +1170,7 @@ TEST_F(TodayServiceCase, QueryAppointmentsById) const auto appointmentsById = service::ScalarArgument::require("appointmentsById", data); - ASSERT_EQ(size_t { 1 }, appointmentsById.size()); + ASSERT_EQ(std::size_t { 1 }, appointmentsById.size()); const auto& appointmentEntry = appointmentsById.front(); EXPECT_EQ(today::getFakeAppointmentId(), service::IdArgument::require("appointmentId", appointmentEntry)) @@ -1186,7 +1200,7 @@ TEST_F(TodayServiceCase, UnimplementedFieldError) ASSERT_TRUE(result.type() == response::Type::Map); const auto& errors = result["errors"]; ASSERT_TRUE(errors.type() == response::Type::List); - ASSERT_EQ(size_t { 1 }, errors.size()); + ASSERT_EQ(std::size_t { 1 }, errors.size()); response::Value error { errors[0] }; ASSERT_TRUE(error.type() == response::Type::Map); ASSERT_EQ( @@ -1219,7 +1233,7 @@ TEST_F(TodayServiceCase, SubscribeNodeChangeMatchingId) const std::shared_ptr& state, response::IdType&& idArg) -> std::shared_ptr { EXPECT_EQ(expectedContext, resolverContext); - EXPECT_EQ(size_t { 13 }, + EXPECT_EQ(std::size_t { 13 }, std::static_pointer_cast(state)->requestId) << "should pass the RequestState to the subscription resolvers"; EXPECT_EQ(today::getFakeTaskId(), idArg); @@ -1366,7 +1380,7 @@ TEST_F(TodayServiceCase, SubscribeNodeChangeFuzzyComparator) const response::IdType fuzzyId { 'f', 'a', 'k' }; EXPECT_EQ(expectedContext, resolverContext); - EXPECT_EQ(size_t { 14 }, + EXPECT_EQ(std::size_t { 14 }, std::static_pointer_cast(state)->requestId) << "should pass the RequestState to the subscription resolvers"; EXPECT_EQ(fuzzyId, idArg); @@ -1514,7 +1528,7 @@ TEST_F(TodayServiceCase, SubscribeNodeChangeMatchingVariable) const std::shared_ptr& state, response::IdType&& idArg) -> std::shared_ptr { EXPECT_EQ(expectedContext, resolverContext); - EXPECT_EQ(size_t { 14 }, + EXPECT_EQ(std::size_t { 14 }, std::static_pointer_cast(state)->requestId) << "should pass the RequestState to the subscription resolvers"; EXPECT_EQ(today::getFakeTaskId(), idArg); @@ -1587,20 +1601,21 @@ TEST_F(TodayServiceCase, DeferredQueryAppointmentsById) auto state = std::make_shared(15); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 15 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 15 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -1615,7 +1630,7 @@ TEST_F(TodayServiceCase, DeferredQueryAppointmentsById) const auto appointmentsById = service::ScalarArgument::require("appointmentsById", data); - ASSERT_EQ(size_t { 1 }, appointmentsById.size()); + ASSERT_EQ(std::size_t { 1 }, appointmentsById.size()); const auto& appointmentEntry = appointmentsById.front(); EXPECT_EQ(today::getFakeAppointmentId(), service::IdArgument::require("appointmentId", appointmentEntry)) @@ -1650,20 +1665,21 @@ TEST_F(TodayServiceCase, NonBlockingQueryAppointmentsById) auto result = _mockService->service ->resolve({ query, {}, std::move(variables), std::launch::async, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 16 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 16 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -1678,7 +1694,7 @@ TEST_F(TodayServiceCase, NonBlockingQueryAppointmentsById) const auto appointmentsById = service::ScalarArgument::require("appointmentsById", data); - ASSERT_EQ(size_t { 1 }, appointmentsById.size()); + ASSERT_EQ(std::size_t { 1 }, appointmentsById.size()); const auto& appointmentEntry = appointmentsById.front(); EXPECT_EQ(today::getFakeAppointmentId(), service::IdArgument::require("appointmentId", appointmentEntry)) @@ -1868,20 +1884,21 @@ TEST_F(TodayServiceCase, QueryAppointmentsThroughUnionTypeFragment) auto state = std::make_shared(20); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 20 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 20 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -1897,7 +1914,7 @@ TEST_F(TodayServiceCase, QueryAppointmentsThroughUnionTypeFragment) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); diff --git a/test/ValidationTests.cpp b/test/ValidationTests.cpp index 06af8b05..de1cb550 100644 --- a/test/ValidationTests.cpp +++ b/test/ValidationTests.cpp @@ -8,6 +8,7 @@ #include "graphqlservice/JSONResponse.h" #include +#include using namespace graphql; @@ -50,7 +51,7 @@ TEST_F(ValidationExamplesCase, CounterExample102) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 2 }); + ASSERT_EQ(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Undefined field type: Dog name: color","locations":[{"line":4,"column":5}]})js", response::toJSON(std::move(errors[0]))) @@ -102,7 +103,7 @@ TEST_F(ValidationExamplesCase, CounterExample104) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Duplicate operation name: getName","locations":[{"line":7,"column":3}]})js", response::toJSON(std::move(errors[0]))) @@ -127,7 +128,7 @@ TEST_F(ValidationExamplesCase, CounterExample105) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Duplicate operation name: dogOperation","locations":[{"line":7,"column":3}]})js", response::toJSON(std::move(errors[0]))) @@ -168,7 +169,7 @@ TEST_F(ValidationExamplesCase, CounterExample107) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Anonymous operation not alone","locations":[{"line":1,"column":1}]})js", response::toJSON(std::move(errors[0]))) @@ -223,7 +224,7 @@ TEST_F(ValidationExamplesCase, CounterExample110) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Subscription with more than one root field name: sub","locations":[{"line":1,"column":1}]})js", response::toJSON(std::move(errors[0]))) @@ -248,7 +249,7 @@ TEST_F(ValidationExamplesCase, CounterExample111) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Subscription with more than one root field name: sub","locations":[{"line":1,"column":1}]})js", response::toJSON(std::move(errors[0]))) @@ -265,7 +266,7 @@ TEST_F(ValidationExamplesCase, CounterExample112) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Subscription with Introspection root field name: sub","locations":[{"line":1,"column":1}]})js", response::toJSON(std::move(errors[0]))) @@ -286,8 +287,8 @@ TEST_F(ValidationExamplesCase, CounterExample113) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 4 }) << "2 undefined fields + 2 unused fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 4 }) << "2 undefined fields + 2 unused fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Undefined field type: Dog name: meowVolume","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -326,8 +327,8 @@ TEST_F(ValidationExamplesCase, CounterExample115) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined field + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined field + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined field type: Pet name: nickname","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -369,8 +370,8 @@ TEST_F(ValidationExamplesCase, CounterExample117) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 3 }) << "2 undefined fields + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 3 }) << "2 undefined fields + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Field on union type: CatOrDog name: name","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -417,8 +418,8 @@ TEST_F(ValidationExamplesCase, CounterExample119) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 conflicting field + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 conflicting field + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Conflicting field type: Dog name: name","locations":[{"line":3,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -481,9 +482,9 @@ TEST_F(ValidationExamplesCase, CounterExample121) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 9 }) + EXPECT_EQ(errors.size(), std::size_t { 9 }) << "4 conflicting fields + 1 missing argument + 4 unused fragments"; - ASSERT_GE(errors.size(), size_t { 4 }); + ASSERT_GE(errors.size(), std::size_t { 4 }); EXPECT_EQ( R"js({"message":"Conflicting field type: Dog name: doesKnowCommand","locations":[{"line":3,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -550,8 +551,8 @@ TEST_F(ValidationExamplesCase, CounterExample123) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 conflicting field + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 conflicting field + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Conflicting field type: Cat name: meowVolume","locations":[{"line":6,"column":5}]})js", response::toJSON(std::move(errors[0]))) @@ -588,8 +589,8 @@ TEST_F(ValidationExamplesCase, CounterExample125) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 invalid field + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 invalid field + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Field on scalar type: Int name: sinceWhen","locations":[{"line":3,"column":5}]})js", response::toJSON(std::move(errors[0]))) @@ -639,7 +640,7 @@ TEST_F(ValidationExamplesCase, CounterExample127) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 3 }) << "3 invalid fields"; + ASSERT_EQ(errors.size(), std::size_t { 3 }) << "3 invalid fields"; EXPECT_EQ( R"js({"message":"Missing fields on non-scalar type: Human","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -687,9 +688,9 @@ TEST_F(ValidationExamplesCase, CounterExample129) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 3 }) + EXPECT_EQ(errors.size(), std::size_t { 3 }) << "1 undefined argument + 1 missing argument + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined argument type: Dog field: doesKnowCommand name: command","locations":[{"line":2,"column":20}]})js", response::toJSON(std::move(errors[0]))) @@ -706,9 +707,9 @@ TEST_F(ValidationExamplesCase, CounterExample130) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 3 }) + EXPECT_EQ(errors.size(), std::size_t { 3 }) << "1 undefined argument + 1 missing argument + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined argument directive: include name: unless","locations":[{"line":2,"column":48}]})js", response::toJSON(std::move(errors[0]))) @@ -808,8 +809,8 @@ TEST_F(ValidationExamplesCase, CounterExample135) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 missing argument + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 missing argument + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Missing argument type: Arguments field: nonNullBooleanArgField name: nonNullBooleanArg","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -826,8 +827,8 @@ TEST_F(ValidationExamplesCase, CounterExample136) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 missing argument + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 missing argument + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Required non-null argument type: Arguments field: nonNullBooleanArgField name: nonNullBooleanArg","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -881,8 +882,8 @@ TEST_F(ValidationExamplesCase, CounterExample138) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 duplicate fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 duplicate fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Duplicate fragment name: fragmentOne","locations":[{"line":11,"column":3}]})js", response::toJSON(std::move(errors[0]))) @@ -937,8 +938,8 @@ TEST_F(ValidationExamplesCase, CounterExample140) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 4 }) << "2 not existing types + 2 unused fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 4 }) << "2 not existing types + 2 unused fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Undefined target type on fragment definition: notOnExistingType name: NotInSchema","locations":[{"line":1,"column":28}]})js", response::toJSON(std::move(errors[0]))) @@ -995,8 +996,8 @@ TEST_F(ValidationExamplesCase, CounterExample142) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 4 }) << "2 not existing types + 2 unused fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 4 }) << "2 not existing types + 2 unused fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Scalar target type on fragment definition: fragOnScalar name: Int","locations":[{"line":1,"column":23}]})js", response::toJSON(std::move(errors[0]))) @@ -1023,8 +1024,8 @@ TEST_F(ValidationExamplesCase, CounterExample143) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Unused fragment definition name: nameFragment","locations":[{"line":1,"column":1}]})js", response::toJSON(std::move(errors[0]))) @@ -1043,8 +1044,8 @@ TEST_F(ValidationExamplesCase, CounterExample144) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined fragment + 1 missing field"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined fragment + 1 missing field"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined fragment spread name: undefinedFragment","locations":[{"line":3,"column":8}]})js", response::toJSON(std::move(errors[0]))) @@ -1073,8 +1074,8 @@ TEST_F(ValidationExamplesCase, CounterExample145) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "2 cyclic fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "2 cyclic fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Cyclic fragment spread name: nameFragment","locations":[{"line":14,"column":7}]})js", response::toJSON(std::move(errors[0]))) @@ -1134,8 +1135,8 @@ TEST_F(ValidationExamplesCase, CounterExample147) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "2 cyclic fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "2 cyclic fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Cyclic fragment spread name: dogFragment","locations":[{"line":19,"column":8}]})js", response::toJSON(std::move(errors[0]))) @@ -1178,8 +1179,8 @@ TEST_F(ValidationExamplesCase, CounterExample149) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 incompatible type + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 incompatible type + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Incompatible target type on inline fragment name: Cat","locations":[{"line":2,"column":8}]})js", response::toJSON(std::move(errors[0]))) @@ -1278,8 +1279,8 @@ TEST_F(ValidationExamplesCase, CounterExample153) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 4 }) << "2 incompatible type + 2 unused fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 4 }) << "2 incompatible type + 2 unused fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Incompatible target type on inline fragment name: Dog","locations":[{"line":2,"column":8}]})js", response::toJSON(std::move(errors[0]))) @@ -1328,8 +1329,8 @@ TEST_F(ValidationExamplesCase, CounterExample155) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 3 }) << "1 incompatible type + 2 unused fragments"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 3 }) << "1 incompatible type + 2 unused fragments"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Incompatible fragment spread target type: Sentient name: sentientFragment","locations":[{"line":2,"column":7}]})js", response::toJSON(std::move(errors[0]))) @@ -1402,9 +1403,9 @@ TEST_F(ValidationExamplesCase, CounterExample158) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 5 }) + EXPECT_EQ(errors.size(), std::size_t { 5 }) << "2 expected values + 2 incompatible arguments + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 4 }); + ASSERT_GE(errors.size(), std::size_t { 4 }); EXPECT_EQ(R"js({"message":"Expected Int value","locations":[{"line":2,"column":24}]})js", response::toJSON(std::move(errors[0]))) << "error should match"; @@ -1447,8 +1448,8 @@ TEST_F(ValidationExamplesCase, CounterExample160) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined field + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined field + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Undefined Input Object field type: ComplexInput name: favoriteCookieFlavor","locations":[{"line":2,"column":45}]})js", response::toJSON(std::move(errors[0]))) @@ -1471,8 +1472,8 @@ TEST_F(ValidationExamplesCase, CounterExample161) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 conflicting field"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 conflicting field"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Conflicting input field name: name","locations":[{"line":2,"column":37}]})js", response::toJSON(std::move(errors[0]))) @@ -1491,8 +1492,8 @@ TEST_F(ValidationExamplesCase, CounterExample162) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 unexpected location"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 unexpected location"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Unexpected location for directive: skip name: QUERY","locations":[{"line":1,"column":7}]})js", response::toJSON(std::move(errors[0]))) @@ -1511,8 +1512,8 @@ TEST_F(ValidationExamplesCase, CounterExample163) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 conflicting directive + 1 unused variable"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 conflicting directive + 1 unused variable"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Conflicting directive name: skip","locations":[{"line":2,"column":24}]})js", response::toJSON(std::move(errors[0]))) @@ -1548,8 +1549,8 @@ TEST_F(ValidationExamplesCase, CounterExample165) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 conflicting variable"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 conflicting variable"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Conflicting variable operation: houseTrainedQuery name: atOtherHomes","locations":[{"line":1,"column":49}]})js", response::toJSON(std::move(errors[0]))) @@ -1646,8 +1647,8 @@ TEST_F(ValidationExamplesCase, CounterExample169) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 4 }) << "4 invalid variable types"; - ASSERT_GE(errors.size(), size_t { 4 }); + EXPECT_EQ(errors.size(), std::size_t { 4 }) << "4 invalid variable types"; + ASSERT_GE(errors.size(), std::size_t { 4 }); EXPECT_EQ( R"js({"message":"Invalid variable type operation: takesCat name: cat","locations":[{"line":1,"column":22}]})js", response::toJSON(std::move(errors[0]))) @@ -1692,8 +1693,8 @@ TEST_F(ValidationExamplesCase, CounterExample171) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined variable name: atOtherHomes","locations":[{"line":3,"column":34}]})js", response::toJSON(std::move(errors[0]))) @@ -1734,8 +1735,8 @@ TEST_F(ValidationExamplesCase, CounterExample173) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined variable name: atOtherHomes","locations":[{"line":8,"column":33}]})js", response::toJSON(std::move(errors[0]))) @@ -1762,8 +1763,8 @@ TEST_F(ValidationExamplesCase, CounterExample174) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined variable name: atOtherHomes","locations":[{"line":12,"column":33}]})js", response::toJSON(std::move(errors[0]))) @@ -1816,8 +1817,8 @@ TEST_F(ValidationExamplesCase, CounterExample176) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined variable name: atOtherHomes","locations":[{"line":14,"column":33}]})js", response::toJSON(std::move(errors[0]))) @@ -1836,8 +1837,8 @@ TEST_F(ValidationExamplesCase, CounterExample177) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 unused variable"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 unused variable"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Unused variable name: atOtherHomes","locations":[{"line":1,"column":22}]})js", response::toJSON(std::move(errors[0]))) @@ -1878,8 +1879,8 @@ TEST_F(ValidationExamplesCase, CounterExample179) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 unused variable"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 unused variable"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Unused variable name: atOtherHomes","locations":[{"line":1,"column":37}]})js", response::toJSON(std::move(errors[0]))) @@ -1908,8 +1909,8 @@ TEST_F(ValidationExamplesCase, CounterExample180) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 unused variable"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 unused variable"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Unused variable name: extra","locations":[{"line":7,"column":51}]})js", response::toJSON(std::move(errors[0]))) @@ -1928,8 +1929,9 @@ TEST_F(ValidationExamplesCase, CounterExample181) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 incompatible variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) + << "1 incompatible variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Incompatible variable type: Int name: Boolean","locations":[{"line":3,"column":33}]})js", response::toJSON(std::move(errors[0]))) @@ -1948,8 +1950,9 @@ TEST_F(ValidationExamplesCase, CounterExample182) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 incompatible variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) + << "1 incompatible variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Expected Scalar variable type","locations":[{"line":3,"column":33}]})js", response::toJSON(std::move(errors[0]))) @@ -1968,8 +1971,9 @@ TEST_F(ValidationExamplesCase, CounterExample183) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 incompatible variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) + << "1 incompatible variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Expected Non-Null variable type","locations":[{"line":3,"column":47}]})js", response::toJSON(std::move(errors[0]))) @@ -2002,8 +2006,9 @@ TEST_F(ValidationExamplesCase, CounterExample185) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 incompatible variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) + << "1 incompatible variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Expected Non-Null variable type","locations":[{"line":3,"column":52}]})js", response::toJSON(std::move(errors[0]))) From 1996b5a3e7230fa88b49d54652a17c4a9b41ac5a Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 11 Sep 2024 21:59:32 -0700 Subject: [PATCH 017/123] chore(cleanup): remove support for experimental coroutines --- doc/awaitable.md | 18 ++++++------ include/graphqlservice/GraphQLService.h | 32 ++++++++++----------- include/graphqlservice/internal/Awaitable.h | 23 +++++---------- samples/today/TodayMock.cpp | 2 +- src/CMakeLists.txt | 8 +----- src/GraphQLService.cpp | 16 +++++------ test/CoroutineTests.cpp | 2 +- 7 files changed, 43 insertions(+), 58 deletions(-) diff --git a/doc/awaitable.md b/doc/awaitable.md index e22a0454..350d055f 100644 --- a/doc/awaitable.md +++ b/doc/awaitable.md @@ -16,7 +16,7 @@ private: virtual ~Concept() = default; [[nodiscard("unexpected call")]] virtual bool await_ready() const = 0; - virtual void await_suspend(coro::coroutine_handle<> h) const = 0; + virtual void await_suspend(std::coroutine_handle<> h) const = 0; virtual void await_resume() const = 0; }; ... @@ -32,7 +32,7 @@ public: // Default to immediate synchronous execution. await_async() : _pimpl { std::static_pointer_cast( - std::make_shared>(std::make_shared())) } + std::make_shared>(std::make_shared())) } { } @@ -41,8 +41,8 @@ public: : _pimpl { ((launch & std::launch::async) == std::launch::async) ? std::static_pointer_cast(std::make_shared>( std::make_shared())) - : std::static_pointer_cast(std::make_shared>( - std::make_shared())) } + : std::static_pointer_cast(std::make_shared>( + std::make_shared())) } { } ... @@ -51,12 +51,12 @@ public: For convenience, it will use `graphql::service::await_worker_thread` if you specify `std::launch::async`, which should have the same behavior as calling `std::async(std::launch::async, ...)` did before. -If you specify any other flags for `std::launch`, it does not honor them. It will use `coro::suspend_never` +If you specify any other flags for `std::launch`, it does not honor them. It will use `std::suspend_never` (an alias for `std::suspend_never` or `std::experimental::suspend_never`), which as the name suggests, continues executing the coroutine without suspending. In other words, `std::launch::deferred` will no longer defer execution as in previous versions, it will execute immediately. -There is also a default constructor which also uses `coro::suspend_never`, so that is the default +There is also a default constructor which also uses `std::suspend_never`, so that is the default behavior anywhere that `await_async` is default-initialized with `{}`. Other than simplification, the big advantage this brings is in the type-erased template constructor. @@ -110,7 +110,7 @@ public: return true; } - void await_suspend(coro::coroutine_handle<> h) const + void await_suspend(std::coroutine_handle<> h) const { h.resume(); } @@ -189,7 +189,7 @@ public: bool await_ready() const noexcept { ... } - void await_suspend(coro::coroutine_handle<> h) const { ... } + void await_suspend(std::coroutine_handle<> h) const { ... } T await_resume() { @@ -245,7 +245,7 @@ public: bool await_ready() const noexcept { ... } - void await_suspend(coro::coroutine_handle<> h) const { ... } + void await_suspend(std::coroutine_handle<> h) const { ... } T await_resume() { ... } diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 7fb7b77c..0e6b6a92 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -161,20 +161,20 @@ enum class [[nodiscard("unnecessary conversion")]] ResolverContext { // Resume coroutine execution on a new worker thread any time co_await is called. This emulates the // behavior of std::async when passing std::launch::async. -struct [[nodiscard("unnecessary construction")]] await_worker_thread : coro::suspend_always +struct [[nodiscard("unnecessary construction")]] await_worker_thread : std::suspend_always { - GRAPHQLSERVICE_EXPORT void await_suspend(coro::coroutine_handle<> h) const; + GRAPHQLSERVICE_EXPORT void await_suspend(std::coroutine_handle<> h) const; }; // Queue coroutine execution on a single dedicated worker thread any time co_await is called from // the thread which created it. -struct [[nodiscard("unnecessary construction")]] await_worker_queue : coro::suspend_always +struct [[nodiscard("unnecessary construction")]] await_worker_queue : std::suspend_always { GRAPHQLSERVICE_EXPORT await_worker_queue(); GRAPHQLSERVICE_EXPORT ~await_worker_queue(); [[nodiscard("unexpected call")]] GRAPHQLSERVICE_EXPORT bool await_ready() const; - GRAPHQLSERVICE_EXPORT void await_suspend(coro::coroutine_handle<> h); + GRAPHQLSERVICE_EXPORT void await_suspend(std::coroutine_handle<> h); private: void resumePending(); @@ -182,7 +182,7 @@ struct [[nodiscard("unnecessary construction")]] await_worker_queue : coro::susp const std::thread::id _startId; std::mutex _mutex {}; std::condition_variable _cv {}; - std::list> _pending {}; + std::list> _pending {}; bool _shutdown = false; std::thread _worker; }; @@ -196,7 +196,7 @@ class [[nodiscard("unnecessary construction")]] await_async final virtual ~Concept() = default; [[nodiscard("unexpected call")]] virtual bool await_ready() const = 0; - virtual void await_suspend(coro::coroutine_handle<> h) const = 0; + virtual void await_suspend(std::coroutine_handle<> h) const = 0; virtual void await_resume() const = 0; }; @@ -213,7 +213,7 @@ class [[nodiscard("unnecessary construction")]] await_async final return _pimpl->await_ready(); } - void await_suspend(coro::coroutine_handle<> h) const final + void await_suspend(std::coroutine_handle<> h) const final { _pimpl->await_suspend(std::move(h)); } @@ -244,7 +244,7 @@ class [[nodiscard("unnecessary construction")]] await_async final GRAPHQLSERVICE_EXPORT await_async(std::launch launch); [[nodiscard("unexpected call")]] GRAPHQLSERVICE_EXPORT bool await_ready() const; - GRAPHQLSERVICE_EXPORT void await_suspend(coro::coroutine_handle<> h) const; + GRAPHQLSERVICE_EXPORT void await_suspend(std::coroutine_handle<> h) const; GRAPHQLSERVICE_EXPORT void await_resume() const; }; @@ -318,12 +318,12 @@ class [[nodiscard("unnecessary construction")]] AwaitableScalar return { _promise.get_future() }; } - coro::suspend_never initial_suspend() const noexcept + std::suspend_never initial_suspend() const noexcept { return {}; } - coro::suspend_never final_suspend() const noexcept + std::suspend_never final_suspend() const noexcept { return {}; } @@ -372,10 +372,10 @@ class [[nodiscard("unnecessary construction")]] AwaitableScalar _value); } - void await_suspend(coro::coroutine_handle<> h) const + void await_suspend(std::coroutine_handle<> h) const { std::thread( - [this](coro::coroutine_handle<> h) noexcept { + [this](std::coroutine_handle<> h) noexcept { std::get>(_value).wait(); h.resume(); }, @@ -448,12 +448,12 @@ class [[nodiscard("unnecessary construction")]] AwaitableObject return { _promise.get_future() }; } - coro::suspend_never initial_suspend() const noexcept + std::suspend_never initial_suspend() const noexcept { return {}; } - coro::suspend_never final_suspend() const noexcept + std::suspend_never final_suspend() const noexcept { return {}; } @@ -497,10 +497,10 @@ class [[nodiscard("unnecessary construction")]] AwaitableObject _value); } - void await_suspend(coro::coroutine_handle<> h) const + void await_suspend(std::coroutine_handle<> h) const { std::thread( - [this](coro::coroutine_handle<> h) noexcept { + [this](std::coroutine_handle<> h) noexcept { std::get>(_value).wait(); h.resume(); }, diff --git a/include/graphqlservice/internal/Awaitable.h b/include/graphqlservice/internal/Awaitable.h index 45097751..046e6a8b 100644 --- a/include/graphqlservice/internal/Awaitable.h +++ b/include/graphqlservice/internal/Awaitable.h @@ -6,16 +6,7 @@ #ifndef GRAPHQLAWAITABLE_H #define GRAPHQLAWAITABLE_H -// clang-format off -#ifdef USE_STD_EXPERIMENTAL_COROUTINE - #include - namespace coro = std::experimental; -#else // !USE_STD_EXPERIMENTAL_COROUTINE - #include - namespace coro = std; -#endif -// clang-format on - +#include #include #include @@ -45,12 +36,12 @@ class [[nodiscard("unnecessary construction")]] Awaitable return { _promise.get_future() }; } - coro::suspend_never initial_suspend() const noexcept + std::suspend_never initial_suspend() const noexcept { return {}; } - coro::suspend_never final_suspend() const noexcept + std::suspend_never final_suspend() const noexcept { return {}; } @@ -74,7 +65,7 @@ class [[nodiscard("unnecessary construction")]] Awaitable return true; } - void await_suspend(coro::coroutine_handle<> h) const + void await_suspend(std::coroutine_handle<> h) const { h.resume(); } @@ -109,12 +100,12 @@ class [[nodiscard("unnecessary construction")]] Awaitable return { _promise.get_future() }; } - coro::suspend_never initial_suspend() const noexcept + std::suspend_never initial_suspend() const noexcept { return {}; } - coro::suspend_never final_suspend() const noexcept + std::suspend_never final_suspend() const noexcept { return {}; } @@ -143,7 +134,7 @@ class [[nodiscard("unnecessary construction")]] Awaitable return true; } - void await_suspend(coro::coroutine_handle<> h) const + void await_suspend(std::coroutine_handle<> h) const { h.resume(); } diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index f07ded28..cb277ed2 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -477,7 +477,7 @@ auto operator co_await(std::chrono::duration<_Rep, _Period> delay) return true; } - void await_suspend(coro::coroutine_handle<> h) noexcept + void await_suspend(std::coroutine_handle<> h) noexcept { h.resume(); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6bab8b34..78d1a63b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -107,13 +107,7 @@ check_coroutine_impl("coroutine" "std" "-fcoroutines" STD_COROUTINE) if(STD_COROUTINE) message(STATUS "Using std coroutine") else() - check_coroutine_impl("experimental/coroutine" "std::experimental" "" STD_EXPERIMENTAL_COROUTINE) - if(STD_EXPERIMENTAL_COROUTINE) - message(STATUS "Using std::experimental coroutine") - target_compile_definitions(graphqlcoro INTERFACE USE_STD_EXPERIMENTAL_COROUTINE) - else() - message(FATAL_ERROR "Missing coroutine support") - endif() + message(FATAL_ERROR "Missing coroutine support") endif() # graphqlpeg diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index 80fe1e62..e45f3349 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -181,10 +181,10 @@ std::string unimplemented_method::getMessage(std::string_view methodName) noexce return oss.str(); } -void await_worker_thread::await_suspend(coro::coroutine_handle<> h) const +void await_worker_thread::await_suspend(std::coroutine_handle<> h) const { std::thread( - [](coro::coroutine_handle<>&& h) { + [](std::coroutine_handle<>&& h) { h.resume(); }, std::move(h)) @@ -215,7 +215,7 @@ bool await_worker_queue::await_ready() const return std::this_thread::get_id() != _startId; } -void await_worker_queue::await_suspend(coro::coroutine_handle<> h) +void await_worker_queue::await_suspend(std::coroutine_handle<> h) { std::unique_lock lock { _mutex }; @@ -234,7 +234,7 @@ void await_worker_queue::resumePending() return _shutdown || !_pending.empty(); }); - std::list> pending; + std::list> pending; std::swap(pending, _pending); @@ -252,7 +252,7 @@ void await_worker_queue::resumePending() // Default to immediate synchronous execution. await_async::await_async() : _pimpl { std::static_pointer_cast( - std::make_shared>(std::make_shared())) } + std::make_shared>(std::make_shared())) } { } @@ -261,8 +261,8 @@ await_async::await_async(std::launch launch) : _pimpl { ((launch & std::launch::async) == std::launch::async) ? std::static_pointer_cast(std::make_shared>( std::make_shared())) - : std::static_pointer_cast(std::make_shared>( - std::make_shared())) } + : std::static_pointer_cast(std::make_shared>( + std::make_shared())) } { } @@ -271,7 +271,7 @@ bool await_async::await_ready() const return _pimpl->await_ready(); } -void await_async::await_suspend(coro::coroutine_handle<> h) const +void await_async::await_suspend(std::coroutine_handle<> h) const { _pimpl->await_suspend(std::move(h)); } diff --git a/test/CoroutineTests.cpp b/test/CoroutineTests.cpp index e78050ab..60933449 100644 --- a/test/CoroutineTests.cpp +++ b/test/CoroutineTests.cpp @@ -68,7 +68,7 @@ TEST_F(CoroutineCase, QueryEverythingSync) })"_graphql; response::Value variables(response::Type::Map); auto state = std::make_shared(1); - const auto worker = std::make_shared(); + const auto worker = std::make_shared(); auto result = _mockService->service ->resolve({ query, "Everything"sv, From 1d24695ab89fd8dc37ed360afa4daa22b90db2e0 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 11 Sep 2024 23:12:13 -0700 Subject: [PATCH 018/123] chore(modules): try building internal headers as modules --- ...st_coroutine.cpp.in => test_coroutine.cpp} | 6 +-- doc/awaitable.md | 2 +- include/graphqlservice/GraphQLClient.h | 5 +- include/graphqlservice/GraphQLResponse.h | 7 ++- include/graphqlservice/GraphQLService.h | 6 ++- .../internal/{Awaitable.h => Awaitable.ixx} | 11 ++--- include/graphqlservice/internal/Version.ixx | 23 +++++++++ src/CMakeLists.txt | 48 ++++++++++++++----- src/ClientGenerator.cpp | 13 +++-- src/GraphQLResponse.cpp | 4 ++ 10 files changed, 92 insertions(+), 33 deletions(-) rename cmake/{test_coroutine.cpp.in => test_coroutine.cpp} (85%) rename include/graphqlservice/internal/{Awaitable.h => Awaitable.ixx} (95%) create mode 100644 include/graphqlservice/internal/Version.ixx diff --git a/cmake/test_coroutine.cpp.in b/cmake/test_coroutine.cpp similarity index 85% rename from cmake/test_coroutine.cpp.in rename to cmake/test_coroutine.cpp index 9ea6c5ac..f3c5f52f 100644 --- a/cmake/test_coroutine.cpp.in +++ b/cmake/test_coroutine.cpp @@ -4,7 +4,7 @@ // combination of headers and namespaces which we want to pass to the CMake // try_compile command. -#include <@COROUTINE_HEADER@> +#include #include struct task @@ -16,12 +16,12 @@ struct task return {}; } - @COROUTINE_NAMESPACE@::suspend_never initial_suspend() noexcept + std::suspend_never initial_suspend() noexcept { return {}; } - @COROUTINE_NAMESPACE@::suspend_never final_suspend() noexcept + std::suspend_never final_suspend() noexcept { return {}; } diff --git a/doc/awaitable.md b/doc/awaitable.md index 350d055f..4d13a6bc 100644 --- a/doc/awaitable.md +++ b/doc/awaitable.md @@ -68,7 +68,7 @@ coroutine when and where it likes. ## Awaitable Results Many APIs which used to return some sort of `std::future` now return an alias for -`graphql::internal::Awaitable<...>`. This template is defined in [Awaitable.h](../include/graphqlservice/internal/Awaitable.h): +`graphql::internal::Awaitable<...>`. This template is defined in [Awaitable.ixx](../include/graphqlservice/internal/Awaitable.ixx): ```cpp template class [[nodiscard("unnecessary construction")]] Awaitable diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index 2aa7835d..a5cd1e32 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -8,13 +8,16 @@ #include "GraphQLResponse.h" -#include "internal/Version.h" #include "internal/DllExports.h" +import Internal.Version; + #include +#include #include #include #include +#include #include #include diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index 777aae54..cd5dbf62 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -6,15 +6,20 @@ #ifndef GRAPHQLRESPONSE_H #define GRAPHQLRESPONSE_H -#include "internal/Awaitable.h" #include "internal/DllExports.h" +import Internal.Awaitable; + +#include #include #include +#include #include +#include #include #include #include +#include #include #include diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 0e6b6a92..6b95464b 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -9,13 +9,15 @@ #include "GraphQLParse.h" #include "GraphQLResponse.h" -#include "internal/Awaitable.h" #include "internal/DllExports.h" #include "internal/SortedMap.h" -#include "internal/Version.h" + +import Internal.Awaitable; +import Internal.Version; #include #include +#include #include #include #include diff --git a/include/graphqlservice/internal/Awaitable.h b/include/graphqlservice/internal/Awaitable.ixx similarity index 95% rename from include/graphqlservice/internal/Awaitable.h rename to include/graphqlservice/internal/Awaitable.ixx index 046e6a8b..50d4ef08 100644 --- a/include/graphqlservice/internal/Awaitable.h +++ b/include/graphqlservice/internal/Awaitable.ixx @@ -1,16 +1,15 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#pragma once - -#ifndef GRAPHQLAWAITABLE_H -#define GRAPHQLAWAITABLE_H +module; #include #include #include -namespace graphql::internal { +export module Internal.Awaitable; + +export namespace graphql::internal { template class [[nodiscard("unnecessary construction")]] Awaitable; @@ -149,5 +148,3 @@ class [[nodiscard("unnecessary construction")]] Awaitable }; } // namespace graphql::internal - -#endif // GRAPHQLAWAITABLE_H diff --git a/include/graphqlservice/internal/Version.ixx b/include/graphqlservice/internal/Version.ixx new file mode 100644 index 00000000..c4769603 --- /dev/null +++ b/include/graphqlservice/internal/Version.ixx @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Version.h" + +export module Internal.Version; + +export namespace graphql::internal { + +namespace version { + +constexpr std::string_view FullVersion = graphql::internal::FullVersion; +constexpr std::size_t MajorVersion = graphql::internal::MajorVersion; +constexpr std::size_t MinorVersion = graphql::internal::MinorVersion; +constexpr std::size_t PatchVersion = graphql::internal::PatchVersion; + +} // namespace version + +using namespace version; + +} // namespace graphql::internal diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 78d1a63b..620c9b8f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,12 +71,20 @@ function(add_bigobj_flag target) endif() endfunction() -add_library(graphqlcoro INTERFACE) -target_compile_features(graphqlcoro INTERFACE cxx_std_20) - -function(check_coroutine_impl COROUTINE_HEADER COROUTINE_NAMESPACE OPTIONAL_FLAGS OUT_RESULT) +file(REAL_PATH ../include/ INCLUDE_ROOT) + +# graphqlawaitable +add_library(graphqlawaitable STATIC) +add_library(cppgraphqlgen::graphqlawaitable ALIAS graphqlawaitable) +target_compile_features(graphqlawaitable PUBLIC cxx_std_20) +target_sources(graphqlawaitable PUBLIC FILE_SET CXX_MODULES +BASE_DIRS + ${INCLUDE_ROOT} +FILES + ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.ixx) + +function(check_coroutine_impl OPTIONAL_FLAGS OUT_RESULT) set(TEST_FILE "test_${OUT_RESULT}.cpp") - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/test_coroutine.cpp.in ${TEST_FILE} @ONLY) try_compile(TEST_RESULT ${CMAKE_CURRENT_BINARY_DIR} @@ -94,7 +102,7 @@ function(check_coroutine_impl COROUTINE_HEADER COROUTINE_NAMESPACE OPTIONAL_FLAG if(TEST_RESULT) # Looks like the optional flag was required, go ahead and add it to the compile options. - target_compile_options(graphqlcoro INTERFACE ${OPTIONAL_FLAG}) + target_compile_options(graphqlawaitable INTERFACE ${OPTIONAL_FLAG}) break() endif() endforeach(OPTIONAL_FLAG) @@ -103,19 +111,27 @@ function(check_coroutine_impl COROUTINE_HEADER COROUTINE_NAMESPACE OPTIONAL_FLAG set(${OUT_RESULT} ${TEST_RESULT} PARENT_SCOPE) endfunction() -check_coroutine_impl("coroutine" "std" "-fcoroutines" STD_COROUTINE) +check_coroutine_impl("-fcoroutines" STD_COROUTINE) if(STD_COROUTINE) message(STATUS "Using std coroutine") else() message(FATAL_ERROR "Missing coroutine support") endif() +# graphqlversion +add_library(graphqlversion STATIC) +add_library(cppgraphqlgen::graphqlversion ALIAS graphqlversion) +target_compile_features(graphqlversion PUBLIC cxx_std_20) +target_sources(graphqlversion PUBLIC FILE_SET CXX_MODULES +BASE_DIRS + ${INCLUDE_ROOT} +FILES + ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx) + # graphqlpeg add_library(graphqlpeg SyntaxTree.cpp) add_library(cppgraphqlgen::graphqlpeg ALIAS graphqlpeg) -target_link_libraries(graphqlpeg PUBLIC - graphqlcoro - taocpp::pegtl) +target_link_libraries(graphqlpeg PUBLIC taocpp::pegtl) target_include_directories(graphqlpeg PUBLIC $ $ @@ -142,7 +158,7 @@ add_library(cppgraphqlgen::graphqlresponse ALIAS graphqlresponse) target_include_directories(graphqlresponse PUBLIC $ $) -target_link_libraries(graphqlresponse PUBLIC graphqlcoro) +target_link_libraries(graphqlresponse PUBLIC graphqlawaitable) if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqlresponse) @@ -163,6 +179,7 @@ if(GRAPHQL_BUILD_SCHEMAGEN OR GRAPHQL_BUILD_CLIENTGEN) GeneratorLoader.cpp GeneratorUtil.cpp) target_link_libraries(generator_util PUBLIC + graphqlversion graphqlpeg graphqlresponse) endif() @@ -324,6 +341,8 @@ add_library(graphqlservice ${INTROSPECTION_SCHEMA_FILES}) add_library(cppgraphqlgen::graphqlservice ALIAS graphqlservice) target_link_libraries(graphqlservice PUBLIC + graphqlversion + graphqlawaitable graphqlpeg graphqlresponse Threads::Threads) @@ -352,6 +371,7 @@ endif() add_library(graphqlclient GraphQLClient.cpp) add_library(cppgraphqlgen::graphqlclient ALIAS graphqlclient) target_link_libraries(graphqlclient PUBLIC + graphqlversion graphqlpeg graphqlresponse) @@ -396,15 +416,17 @@ if(GRAPHQL_USE_RAPIDJSON) endif() install(TARGETS + graphqlawaitable + graphqlversion graphqlclient graphqlpeg - graphqlcoro graphqlresponse graphqlservice EXPORT cppgraphqlgen-targets RUNTIME DESTINATION bin ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) + LIBRARY DESTINATION lib + FILE_SET CXX_MODULES DESTINATION include) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/GraphQLClient.h diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index da7802ac..0d13990a 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import Internal.Version; + #include "ClientGenerator.h" #include "GeneratorUtil.h" -#include "graphqlservice/internal/Version.h" - #include "graphqlservice/introspection/IntrospectionSchema.h" #ifdef _MSC_VER @@ -28,6 +28,7 @@ #include #include #include +#include using namespace std::literals; @@ -171,12 +172,12 @@ bool Generator::outputHeader() const noexcept IncludeGuardScope includeGuard { headerFile, std::filesystem::path(_headerPath).filename().string() }; - headerFile << R"cpp(#include "graphqlservice/GraphQLClient.h" + headerFile << R"cpp(import Internal.Version; + +#include "graphqlservice/GraphQLClient.h" #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" -#include "graphqlservice/internal/Version.h" - // Check if the library version is compatible with clientgen )cpp" << graphql::internal::MajorVersion << R"cpp(.)cpp" << graphql::internal::MinorVersion << R"cpp(.0 @@ -187,8 +188,10 @@ static_assert(graphql::internal::MinorVersion == )cpp" << graphql::internal::MinorVersion << R"cpp(, "regenerate with clientgen: minor version mismatch"); +#include #include #include +#include #include )cpp"; diff --git a/src/GraphQLResponse.cpp b/src/GraphQLResponse.cpp index 14e958e0..25b4ba56 100644 --- a/src/GraphQLResponse.cpp +++ b/src/GraphQLResponse.cpp @@ -7,11 +7,15 @@ #include #include +#include #include #include #include #include +#include +#include #include +#include namespace graphql::response { From decc8e62b802e921e1be13333b1d449ffb056ec3 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 11 Sep 2024 23:20:05 -0700 Subject: [PATCH 019/123] fix(cmake): update the check_coroutine_impl function --- src/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 620c9b8f..db9cf617 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -84,7 +84,8 @@ FILES ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.ixx) function(check_coroutine_impl OPTIONAL_FLAGS OUT_RESULT) - set(TEST_FILE "test_${OUT_RESULT}.cpp") + set(TEST_FILE "test_coroutine.cpp") + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/${TEST_FILE} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) try_compile(TEST_RESULT ${CMAKE_CURRENT_BINARY_DIR} From 1d3a5363c4d800aaaaeb941eb4e80c536ba0b037 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 11 Sep 2024 23:32:40 -0700 Subject: [PATCH 020/123] fix(buiild): remove duplicate includes and specify C++20 --- include/graphqlservice/GraphQLClient.h | 2 -- include/graphqlservice/GraphQLService.h | 6 ------ src/CMakeLists.txt | 6 ++++++ src/ClientGenerator.cpp | 4 ---- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index a5cd1e32..e2ac7ef3 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -13,11 +13,9 @@ import Internal.Version; #include -#include #include #include #include -#include #include #include diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 6b95464b..cc6812ae 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -17,10 +17,6 @@ import Internal.Version; #include #include -#include -#include -#include -#include #include #include #include @@ -29,9 +25,7 @@ import Internal.Version; #include #include #include -#include #include -#include #include #include #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db9cf617..9060a20e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -132,6 +132,7 @@ FILES # graphqlpeg add_library(graphqlpeg SyntaxTree.cpp) add_library(cppgraphqlgen::graphqlpeg ALIAS graphqlpeg) +target_compile_features(graphqlpeg PUBLIC cxx_std_20) target_link_libraries(graphqlpeg PUBLIC taocpp::pegtl) target_include_directories(graphqlpeg PUBLIC $ @@ -156,6 +157,7 @@ add_library(graphqlresponse Base64.cpp GraphQLResponse.cpp) add_library(cppgraphqlgen::graphqlresponse ALIAS graphqlresponse) +target_compile_features(graphqlresponse PUBLIC cxx_std_20) target_include_directories(graphqlresponse PUBLIC $ $) @@ -179,6 +181,7 @@ if(GRAPHQL_BUILD_SCHEMAGEN OR GRAPHQL_BUILD_CLIENTGEN) SchemaLoader.cpp GeneratorLoader.cpp GeneratorUtil.cpp) + target_compile_features(generator_util PUBLIC cxx_std_20) target_link_libraries(generator_util PUBLIC graphqlversion graphqlpeg @@ -341,6 +344,7 @@ add_library(graphqlservice Introspection.cpp ${INTROSPECTION_SCHEMA_FILES}) add_library(cppgraphqlgen::graphqlservice ALIAS graphqlservice) +target_compile_features(graphqlservice PUBLIC cxx_std_20) target_link_libraries(graphqlservice PUBLIC graphqlversion graphqlawaitable @@ -371,6 +375,7 @@ endif() # graphqlclient add_library(graphqlclient GraphQLClient.cpp) add_library(cppgraphqlgen::graphqlclient ALIAS graphqlclient) +target_compile_features(graphqlclient PUBLIC cxx_std_20) target_link_libraries(graphqlclient PUBLIC graphqlversion graphqlpeg @@ -400,6 +405,7 @@ if(GRAPHQL_USE_RAPIDJSON) set(BUILD_GRAPHQLJSON ON) add_library(graphqljson JSONResponse.cpp) add_library(cppgraphqlgen::graphqljson ALIAS graphqljson) + target_compile_features(graphqljson PUBLIC cxx_std_20) target_link_libraries(graphqljson PUBLIC graphqlresponse) target_include_directories(graphqljson SYSTEM PRIVATE ${RAPIDJSON_INCLUDE_DIRS}) diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 0d13990a..16552b09 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -21,14 +21,12 @@ import Internal.Version; #endif // _MSC_VER #include -#include #include #include #include #include #include #include -#include using namespace std::literals; @@ -188,10 +186,8 @@ static_assert(graphql::internal::MinorVersion == )cpp" << graphql::internal::MinorVersion << R"cpp(, "regenerate with clientgen: minor version mismatch"); -#include #include #include -#include #include )cpp"; From a9120e4c94f79e1340cf19f78662a4ae5f07daea Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 15:44:47 -0700 Subject: [PATCH 021/123] fix(modules): consistent Internal.Version module usage --- include/graphqlservice/GraphQLClient.h | 2 -- include/graphqlservice/GraphQLService.h | 1 - include/graphqlservice/internal/Schema.h | 1 - .../graphqlservice/introspection/IntrospectionSchema.h | 2 ++ samples/client/benchmark/BenchmarkClient.h | 2 +- samples/client/multiple/MultipleQueriesClient.h | 2 +- samples/client/mutate/MutateClient.h | 2 +- samples/client/nestedinput/NestedInputClient.h | 2 +- samples/client/query/QueryClient.h | 2 +- samples/client/subscribe/SubscribeClient.h | 2 +- samples/learn/schema/StarWarsSchema.h | 2 ++ samples/proxy/query/ProxyClient.h | 2 +- samples/proxy/schema/ProxySchema.h | 2 ++ samples/today/nointrospection/TodaySchema.h | 2 ++ samples/today/schema/TodaySchema.h | 2 ++ samples/validation/schema/ValidationSchema.h | 2 ++ src/ClientGenerator.cpp | 10 +++++----- src/SchemaGenerator.cpp | 4 ++++ src/introspection/IntrospectionSchema.h | 2 ++ 19 files changed, 30 insertions(+), 16 deletions(-) diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index e2ac7ef3..365e4029 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -10,8 +10,6 @@ #include "internal/DllExports.h" -import Internal.Version; - #include #include #include diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index cc6812ae..81ad7bde 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -13,7 +13,6 @@ #include "internal/SortedMap.h" import Internal.Awaitable; -import Internal.Version; #include #include diff --git a/include/graphqlservice/internal/Schema.h b/include/graphqlservice/internal/Schema.h index 801d3eda..6628a6f5 100644 --- a/include/graphqlservice/internal/Schema.h +++ b/include/graphqlservice/internal/Schema.h @@ -8,7 +8,6 @@ #include "DllExports.h" #include "SortedMap.h" -#include "Version.h" #include #include diff --git a/include/graphqlservice/introspection/IntrospectionSchema.h b/include/graphqlservice/introspection/IntrospectionSchema.h index 363d67f2..13683cb7 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.h +++ b/include/graphqlservice/introspection/IntrospectionSchema.h @@ -13,6 +13,8 @@ #include "graphqlservice/internal/Schema.h" +import Internal.Version; + // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/samples/client/benchmark/BenchmarkClient.h b/samples/client/benchmark/BenchmarkClient.h index f7c4e41e..f3dc46a1 100644 --- a/samples/client/benchmark/BenchmarkClient.h +++ b/samples/client/benchmark/BenchmarkClient.h @@ -12,7 +12,7 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" -#include "graphqlservice/internal/Version.h" +import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); diff --git a/samples/client/multiple/MultipleQueriesClient.h b/samples/client/multiple/MultipleQueriesClient.h index af157461..52e42773 100644 --- a/samples/client/multiple/MultipleQueriesClient.h +++ b/samples/client/multiple/MultipleQueriesClient.h @@ -12,7 +12,7 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" -#include "graphqlservice/internal/Version.h" +import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); diff --git a/samples/client/mutate/MutateClient.h b/samples/client/mutate/MutateClient.h index a2f304eb..fab51c20 100644 --- a/samples/client/mutate/MutateClient.h +++ b/samples/client/mutate/MutateClient.h @@ -12,7 +12,7 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" -#include "graphqlservice/internal/Version.h" +import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); diff --git a/samples/client/nestedinput/NestedInputClient.h b/samples/client/nestedinput/NestedInputClient.h index 78eefa17..16d4dbf6 100644 --- a/samples/client/nestedinput/NestedInputClient.h +++ b/samples/client/nestedinput/NestedInputClient.h @@ -12,7 +12,7 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" -#include "graphqlservice/internal/Version.h" +import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); diff --git a/samples/client/query/QueryClient.h b/samples/client/query/QueryClient.h index fb89bcdd..5502c9e5 100644 --- a/samples/client/query/QueryClient.h +++ b/samples/client/query/QueryClient.h @@ -12,7 +12,7 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" -#include "graphqlservice/internal/Version.h" +import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); diff --git a/samples/client/subscribe/SubscribeClient.h b/samples/client/subscribe/SubscribeClient.h index 5d69e191..aa726d7b 100644 --- a/samples/client/subscribe/SubscribeClient.h +++ b/samples/client/subscribe/SubscribeClient.h @@ -12,7 +12,7 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" -#include "graphqlservice/internal/Version.h" +import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); diff --git a/samples/learn/schema/StarWarsSchema.h b/samples/learn/schema/StarWarsSchema.h index 2511eac0..8f715b5e 100644 --- a/samples/learn/schema/StarWarsSchema.h +++ b/samples/learn/schema/StarWarsSchema.h @@ -13,6 +13,8 @@ #include "graphqlservice/internal/Schema.h" +import Internal.Version; + // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/samples/proxy/query/ProxyClient.h b/samples/proxy/query/ProxyClient.h index 73b15dee..00690b56 100644 --- a/samples/proxy/query/ProxyClient.h +++ b/samples/proxy/query/ProxyClient.h @@ -12,7 +12,7 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" -#include "graphqlservice/internal/Version.h" +import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); diff --git a/samples/proxy/schema/ProxySchema.h b/samples/proxy/schema/ProxySchema.h index eebe09e9..6d57c60a 100644 --- a/samples/proxy/schema/ProxySchema.h +++ b/samples/proxy/schema/ProxySchema.h @@ -13,6 +13,8 @@ #include "graphqlservice/internal/Schema.h" +import Internal.Version; + // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/samples/today/nointrospection/TodaySchema.h b/samples/today/nointrospection/TodaySchema.h index ef18f867..35c41b6e 100644 --- a/samples/today/nointrospection/TodaySchema.h +++ b/samples/today/nointrospection/TodaySchema.h @@ -13,6 +13,8 @@ #include "graphqlservice/internal/Schema.h" +import Internal.Version; + // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/samples/today/schema/TodaySchema.h b/samples/today/schema/TodaySchema.h index ef18f867..35c41b6e 100644 --- a/samples/today/schema/TodaySchema.h +++ b/samples/today/schema/TodaySchema.h @@ -13,6 +13,8 @@ #include "graphqlservice/internal/Schema.h" +import Internal.Version; + // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/samples/validation/schema/ValidationSchema.h b/samples/validation/schema/ValidationSchema.h index 66208163..37eb426b 100644 --- a/samples/validation/schema/ValidationSchema.h +++ b/samples/validation/schema/ValidationSchema.h @@ -13,6 +13,8 @@ #include "graphqlservice/internal/Schema.h" +import Internal.Version; + // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 16552b09..c8e43f04 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import Internal.Version; - #include "ClientGenerator.h" #include "GeneratorUtil.h" #include "graphqlservice/introspection/IntrospectionSchema.h" +import Internal.Version; + #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 26495) @@ -170,12 +170,12 @@ bool Generator::outputHeader() const noexcept IncludeGuardScope includeGuard { headerFile, std::filesystem::path(_headerPath).filename().string() }; - headerFile << R"cpp(import Internal.Version; - -#include "graphqlservice/GraphQLClient.h" + headerFile << R"cpp(#include "graphqlservice/GraphQLClient.h" #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +import Internal.Version; + // Check if the library version is compatible with clientgen )cpp" << graphql::internal::MajorVersion << R"cpp(.)cpp" << graphql::internal::MinorVersion << R"cpp(.0 diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index cd0baf00..c3d58a19 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -4,6 +4,8 @@ #include "SchemaGenerator.h" #include "GeneratorUtil.h" +import Internal.Version; + #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 26495) @@ -115,6 +117,8 @@ bool Generator::outputHeader() const noexcept #include "graphqlservice/internal/Schema.h" +import Internal.Version; + // Check if the library version is compatible with schemagen )cpp" << graphql::internal::MajorVersion << R"cpp(.)cpp" << graphql::internal::MinorVersion << R"cpp(.0 diff --git a/src/introspection/IntrospectionSchema.h b/src/introspection/IntrospectionSchema.h index 363d67f2..13683cb7 100644 --- a/src/introspection/IntrospectionSchema.h +++ b/src/introspection/IntrospectionSchema.h @@ -13,6 +13,8 @@ #include "graphqlservice/internal/Schema.h" +import Internal.Version; + // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); From 591275a436dc1bfc34ec9c4aba3cca1ff1d92009 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 16:02:44 -0700 Subject: [PATCH 022/123] fix(includes): move redundant headers to header that uses them --- include/graphqlservice/GraphQLClient.h | 3 ++- include/graphqlservice/GraphQLResponse.h | 3 --- include/graphqlservice/GraphQLService.h | 2 ++ samples/today/TodayMock.cpp | 1 - 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index 365e4029..67489df6 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -10,11 +10,12 @@ #include "internal/DllExports.h" +import Internal.Awaitable; + #include #include #include #include -#include #include namespace graphql::client { diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index cd5dbf62..cabbeda7 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -10,16 +10,13 @@ import Internal.Awaitable; -#include #include #include -#include #include #include #include #include #include -#include #include #include diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 81ad7bde..8a4dad24 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -16,6 +16,8 @@ import Internal.Awaitable; #include #include +#include +#include #include #include #include diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index cb277ed2..53b0b35b 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include From 836e5b1b0074493a378aa9cf33f7caca565fd136 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 16:56:08 -0700 Subject: [PATCH 023/123] fix: ignore vc140.pdb that VS keeps dropping --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0f77c1a4..696df878 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ settings.json build/ install/ isenseconfig/ +vc140.pdb From 85053f5633d71256536be9f0902901403c742343 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 16:56:52 -0700 Subject: [PATCH 024/123] fix(includes): try moving all imports after system includes --- include/graphqlservice/GraphQLClient.h | 4 ++-- include/graphqlservice/GraphQLResponse.h | 4 ++-- include/graphqlservice/GraphQLService.h | 4 ++-- .../introspection/IntrospectionSchema.h | 10 +++++----- samples/client/benchmark/BenchmarkClient.h | 8 ++++---- samples/client/multiple/MultipleQueriesClient.h | 8 ++++---- samples/client/mutate/MutateClient.h | 8 ++++---- samples/client/nestedinput/NestedInputClient.h | 8 ++++---- samples/client/query/QueryClient.h | 8 ++++---- samples/client/subscribe/SubscribeClient.h | 8 ++++---- samples/learn/schema/StarWarsSchema.h | 10 +++++----- samples/proxy/query/ProxyClient.h | 8 ++++---- samples/proxy/schema/ProxySchema.h | 10 +++++----- samples/today/nointrospection/TodaySchema.h | 10 +++++----- samples/today/schema/TodaySchema.h | 10 +++++----- samples/validation/schema/ValidationSchema.h | 10 +++++----- src/ClientGenerator.cpp | 12 ++++++------ src/SchemaGenerator.cpp | 14 +++++++------- src/introspection/IntrospectionSchema.h | 10 +++++----- 19 files changed, 82 insertions(+), 82 deletions(-) diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index 67489df6..5fcb9bee 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -10,14 +10,14 @@ #include "internal/DllExports.h" -import Internal.Awaitable; - #include #include #include #include #include +import Internal.Awaitable; + namespace graphql::client { // Errors may specify the line number and column number where the error occurred. diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index cabbeda7..7498da14 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -8,8 +8,6 @@ #include "internal/DllExports.h" -import Internal.Awaitable; - #include #include #include @@ -20,6 +18,8 @@ import Internal.Awaitable; #include #include +import Internal.Awaitable; + namespace graphql::response { // GraphQL responses are not technically JSON-specific, although that is probably the most common diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 8a4dad24..0633ab09 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -12,8 +12,6 @@ #include "internal/DllExports.h" #include "internal/SortedMap.h" -import Internal.Awaitable; - #include #include #include @@ -31,6 +29,8 @@ import Internal.Awaitable; #include #include +import Internal.Awaitable; + namespace graphql { namespace schema { diff --git a/include/graphqlservice/introspection/IntrospectionSchema.h b/include/graphqlservice/introspection/IntrospectionSchema.h index 13683cb7..eba4825d 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.h +++ b/include/graphqlservice/introspection/IntrospectionSchema.h @@ -13,17 +13,17 @@ #include "graphqlservice/internal/Schema.h" +#include +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); -#include -#include -#include -#include - namespace graphql { namespace introspection { diff --git a/samples/client/benchmark/BenchmarkClient.h b/samples/client/benchmark/BenchmarkClient.h index f3dc46a1..daf02ef3 100644 --- a/samples/client/benchmark/BenchmarkClient.h +++ b/samples/client/benchmark/BenchmarkClient.h @@ -12,16 +12,16 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); -#include -#include -#include - namespace graphql::client { /// diff --git a/samples/client/multiple/MultipleQueriesClient.h b/samples/client/multiple/MultipleQueriesClient.h index 52e42773..3b5f7efb 100644 --- a/samples/client/multiple/MultipleQueriesClient.h +++ b/samples/client/multiple/MultipleQueriesClient.h @@ -12,16 +12,16 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); -#include -#include -#include - namespace graphql::client { /// diff --git a/samples/client/mutate/MutateClient.h b/samples/client/mutate/MutateClient.h index fab51c20..8e862ab7 100644 --- a/samples/client/mutate/MutateClient.h +++ b/samples/client/mutate/MutateClient.h @@ -12,16 +12,16 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); -#include -#include -#include - namespace graphql::client { /// diff --git a/samples/client/nestedinput/NestedInputClient.h b/samples/client/nestedinput/NestedInputClient.h index 16d4dbf6..b914cad6 100644 --- a/samples/client/nestedinput/NestedInputClient.h +++ b/samples/client/nestedinput/NestedInputClient.h @@ -12,16 +12,16 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); -#include -#include -#include - namespace graphql::client { /// diff --git a/samples/client/query/QueryClient.h b/samples/client/query/QueryClient.h index 5502c9e5..7953c0dc 100644 --- a/samples/client/query/QueryClient.h +++ b/samples/client/query/QueryClient.h @@ -12,16 +12,16 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); -#include -#include -#include - namespace graphql::client { /// diff --git a/samples/client/subscribe/SubscribeClient.h b/samples/client/subscribe/SubscribeClient.h index aa726d7b..3f841a0e 100644 --- a/samples/client/subscribe/SubscribeClient.h +++ b/samples/client/subscribe/SubscribeClient.h @@ -12,16 +12,16 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); -#include -#include -#include - namespace graphql::client { /// diff --git a/samples/learn/schema/StarWarsSchema.h b/samples/learn/schema/StarWarsSchema.h index 8f715b5e..b62f53da 100644 --- a/samples/learn/schema/StarWarsSchema.h +++ b/samples/learn/schema/StarWarsSchema.h @@ -13,17 +13,17 @@ #include "graphqlservice/internal/Schema.h" +#include +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); -#include -#include -#include -#include - namespace graphql { namespace learn { diff --git a/samples/proxy/query/ProxyClient.h b/samples/proxy/query/ProxyClient.h index 00690b56..5ff9c4e6 100644 --- a/samples/proxy/query/ProxyClient.h +++ b/samples/proxy/query/ProxyClient.h @@ -12,16 +12,16 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); -#include -#include -#include - namespace graphql::client { /// diff --git a/samples/proxy/schema/ProxySchema.h b/samples/proxy/schema/ProxySchema.h index 6d57c60a..c6100aa5 100644 --- a/samples/proxy/schema/ProxySchema.h +++ b/samples/proxy/schema/ProxySchema.h @@ -13,17 +13,17 @@ #include "graphqlservice/internal/Schema.h" +#include +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); -#include -#include -#include -#include - namespace graphql { namespace proxy { namespace object { diff --git a/samples/today/nointrospection/TodaySchema.h b/samples/today/nointrospection/TodaySchema.h index 35c41b6e..89d700ab 100644 --- a/samples/today/nointrospection/TodaySchema.h +++ b/samples/today/nointrospection/TodaySchema.h @@ -13,17 +13,17 @@ #include "graphqlservice/internal/Schema.h" +#include +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); -#include -#include -#include -#include - namespace graphql { namespace today { diff --git a/samples/today/schema/TodaySchema.h b/samples/today/schema/TodaySchema.h index 35c41b6e..89d700ab 100644 --- a/samples/today/schema/TodaySchema.h +++ b/samples/today/schema/TodaySchema.h @@ -13,17 +13,17 @@ #include "graphqlservice/internal/Schema.h" +#include +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); -#include -#include -#include -#include - namespace graphql { namespace today { diff --git a/samples/validation/schema/ValidationSchema.h b/samples/validation/schema/ValidationSchema.h index 37eb426b..8e410b6d 100644 --- a/samples/validation/schema/ValidationSchema.h +++ b/samples/validation/schema/ValidationSchema.h @@ -13,17 +13,17 @@ #include "graphqlservice/internal/Schema.h" +#include +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); -#include -#include -#include -#include - namespace graphql { namespace validation { diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index c8e43f04..40abe947 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -6,8 +6,6 @@ #include "graphqlservice/introspection/IntrospectionSchema.h" -import Internal.Version; - #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 26495) @@ -28,6 +26,8 @@ import Internal.Version; #include #include +import Internal.Version; + using namespace std::literals; namespace graphql::generator::client { @@ -174,6 +174,10 @@ bool Generator::outputHeader() const noexcept #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with clientgen )cpp" @@ -186,10 +190,6 @@ static_assert(graphql::internal::MinorVersion == )cpp" << graphql::internal::MinorVersion << R"cpp(, "regenerate with clientgen: minor version mismatch"); -#include -#include -#include - )cpp"; PendingBlankLine pendingSeparator { headerFile }; diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index c3d58a19..9cd1ebbd 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -4,8 +4,6 @@ #include "SchemaGenerator.h" #include "GeneratorUtil.h" -import Internal.Version; - #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 26495) @@ -28,6 +26,8 @@ import Internal.Version; #include #include +import Internal.Version; + using namespace std::literals; namespace graphql::generator::schema { @@ -117,6 +117,11 @@ bool Generator::outputHeader() const noexcept #include "graphqlservice/internal/Schema.h" +#include +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with schemagen )cpp" @@ -129,11 +134,6 @@ static_assert(graphql::internal::MinorVersion == )cpp" << graphql::internal::MinorVersion << R"cpp(, "regenerate with schemagen: minor version mismatch"); -#include -#include -#include -#include - )cpp"; NamespaceScope graphqlNamespace { headerFile, "graphql" }; diff --git a/src/introspection/IntrospectionSchema.h b/src/introspection/IntrospectionSchema.h index 13683cb7..eba4825d 100644 --- a/src/introspection/IntrospectionSchema.h +++ b/src/introspection/IntrospectionSchema.h @@ -13,17 +13,17 @@ #include "graphqlservice/internal/Schema.h" +#include +#include +#include +#include + import Internal.Version; // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); -#include -#include -#include -#include - namespace graphql { namespace introspection { From 0e74aaef40f0a4833c1a0eb85b625d90e74bd7d0 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 17:01:38 -0700 Subject: [PATCH 025/123] chore: disable macOS build on each push --- .github/workflows/macos.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 70cea90b..78dae2ec 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -1,6 +1,8 @@ name: macOS -on: [push, pull_request] +# Turning off macOS CI build since Apple Clang doesn't support C++20 modules +#on: [push, pull_request] +on: [pull_request] jobs: xcode: From e587a4bf310f6e69fc9bd360cfc84b4f2481d7c8 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 20:59:38 -0700 Subject: [PATCH 026/123] feat(modules): finish wrapping modules around headers --- include/graphqlservice/GraphQL.Internal.ixx | 13 + include/graphqlservice/GraphQLClient.h | 2 - include/graphqlservice/GraphQLResponse.h | 3 +- include/graphqlservice/GraphQLService.h | 3 +- include/graphqlservice/internal/Awaitable.h | 153 ++++++++++ include/graphqlservice/internal/Awaitable.ixx | 143 +-------- include/graphqlservice/internal/Base64.ixx | 22 ++ include/graphqlservice/internal/Grammar.ixx | 287 ++++++++++++++++++ .../graphqlservice/internal/Introspection.ixx | 102 +++++++ include/graphqlservice/internal/Schema.ixx | 57 ++++ include/graphqlservice/internal/SortedMap.ixx | 51 ++++ .../graphqlservice/internal/SyntaxTree.ixx | 23 ++ include/graphqlservice/internal/Version.ixx | 2 +- .../introspection/IntrospectionSchema.h | 3 +- samples/client/benchmark/BenchmarkClient.h | 4 +- .../client/multiple/MultipleQueriesClient.h | 4 +- samples/client/mutate/MutateClient.h | 4 +- .../client/nestedinput/NestedInputClient.h | 4 +- samples/client/query/QueryClient.h | 4 +- samples/client/subscribe/SubscribeClient.h | 4 +- samples/learn/schema/StarWarsSchema.h | 3 +- samples/proxy/query/ProxyClient.h | 4 +- samples/proxy/schema/ProxySchema.h | 3 +- samples/today/nointrospection/TodaySchema.h | 3 +- samples/today/schema/TodaySchema.h | 3 +- samples/validation/schema/ValidationSchema.h | 3 +- src/CMakeLists.txt | 33 +- src/ClientGenerator.cpp | 7 +- src/SchemaGenerator.cpp | 7 +- src/introspection/IntrospectionSchema.h | 3 +- 30 files changed, 769 insertions(+), 188 deletions(-) create mode 100644 include/graphqlservice/GraphQL.Internal.ixx create mode 100644 include/graphqlservice/internal/Awaitable.h create mode 100644 include/graphqlservice/internal/Base64.ixx create mode 100644 include/graphqlservice/internal/Grammar.ixx create mode 100644 include/graphqlservice/internal/Introspection.ixx create mode 100644 include/graphqlservice/internal/Schema.ixx create mode 100644 include/graphqlservice/internal/SortedMap.ixx create mode 100644 include/graphqlservice/internal/SyntaxTree.ixx diff --git a/include/graphqlservice/GraphQL.Internal.ixx b/include/graphqlservice/GraphQL.Internal.ixx new file mode 100644 index 00000000..c0e84699 --- /dev/null +++ b/include/graphqlservice/GraphQL.Internal.ixx @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +export module GraphQL.Internal; + +export import :Awaitable; +export import :Base64; +export import :Grammar; +export import :Introspection; +export import :Schema; +export import :SortedMap; +export import :SyntaxTree; +export import :Version; diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index 5fcb9bee..2adf34e7 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -16,8 +16,6 @@ #include #include -import Internal.Awaitable; - namespace graphql::client { // Errors may specify the line number and column number where the error occurred. diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index 7498da14..f155c04f 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -7,6 +7,7 @@ #define GRAPHQLRESPONSE_H #include "internal/DllExports.h" +#include "internal/Awaitable.h" #include #include @@ -18,8 +19,6 @@ #include #include -import Internal.Awaitable; - namespace graphql::response { // GraphQL responses are not technically JSON-specific, although that is probably the most common diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 0633ab09..a4843924 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -9,6 +9,7 @@ #include "GraphQLParse.h" #include "GraphQLResponse.h" +#include "internal/Awaitable.h" #include "internal/DllExports.h" #include "internal/SortedMap.h" @@ -29,8 +30,6 @@ #include #include -import Internal.Awaitable; - namespace graphql { namespace schema { diff --git a/include/graphqlservice/internal/Awaitable.h b/include/graphqlservice/internal/Awaitable.h new file mode 100644 index 00000000..046e6a8b --- /dev/null +++ b/include/graphqlservice/internal/Awaitable.h @@ -0,0 +1,153 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#ifndef GRAPHQLAWAITABLE_H +#define GRAPHQLAWAITABLE_H + +#include +#include +#include + +namespace graphql::internal { + +template +class [[nodiscard("unnecessary construction")]] Awaitable; + +template <> +class [[nodiscard("unnecessary construction")]] Awaitable +{ +public: + Awaitable(std::future value) + : _value { std::move(value) } + { + } + + void get() + { + _value.get(); + } + + struct promise_type + { + [[nodiscard("unnecessary construction")]] Awaitable get_return_object() noexcept + { + return { _promise.get_future() }; + } + + std::suspend_never initial_suspend() const noexcept + { + return {}; + } + + std::suspend_never final_suspend() const noexcept + { + return {}; + } + + void return_void() noexcept + { + _promise.set_value(); + } + + void unhandled_exception() noexcept + { + _promise.set_exception(std::current_exception()); + } + + private: + std::promise _promise; + }; + + [[nodiscard("unexpected call")]] constexpr bool await_ready() const noexcept + { + return true; + } + + void await_suspend(std::coroutine_handle<> h) const + { + h.resume(); + } + + void await_resume() + { + _value.get(); + } + +private: + std::future _value; +}; + +template +class [[nodiscard("unnecessary construction")]] Awaitable +{ +public: + Awaitable(std::future value) + : _value { std::move(value) } + { + } + + [[nodiscard("unnecessary construction")]] T get() + { + return _value.get(); + } + + struct promise_type + { + [[nodiscard("unnecessary construction")]] Awaitable get_return_object() noexcept + { + return { _promise.get_future() }; + } + + std::suspend_never initial_suspend() const noexcept + { + return {}; + } + + std::suspend_never final_suspend() const noexcept + { + return {}; + } + + void return_value(const T& value) noexcept(std::is_nothrow_copy_constructible_v) + { + _promise.set_value(value); + } + + void return_value(T&& value) noexcept(std::is_nothrow_move_constructible_v) + { + _promise.set_value(std::move(value)); + } + + void unhandled_exception() noexcept + { + _promise.set_exception(std::current_exception()); + } + + private: + std::promise _promise; + }; + + [[nodiscard("unexpected call")]] constexpr bool await_ready() const noexcept + { + return true; + } + + void await_suspend(std::coroutine_handle<> h) const + { + h.resume(); + } + + [[nodiscard("unnecessary construction")]] T await_resume() + { + return _value.get(); + } + +private: + std::future _value; +}; + +} // namespace graphql::internal + +#endif // GRAPHQLAWAITABLE_H diff --git a/include/graphqlservice/internal/Awaitable.ixx b/include/graphqlservice/internal/Awaitable.ixx index 50d4ef08..261399e4 100644 --- a/include/graphqlservice/internal/Awaitable.ixx +++ b/include/graphqlservice/internal/Awaitable.ixx @@ -3,148 +3,21 @@ module; -#include -#include -#include +#include "Awaitable.h" -export module Internal.Awaitable; +export module GraphQL.Internal:Awaitable; -export namespace graphql::internal { - -template -class [[nodiscard("unnecessary construction")]] Awaitable; - -template <> -class [[nodiscard("unnecessary construction")]] Awaitable -{ -public: - Awaitable(std::future value) - : _value { std::move(value) } - { - } - - void get() - { - _value.get(); - } - - struct promise_type - { - [[nodiscard("unnecessary construction")]] Awaitable get_return_object() noexcept - { - return { _promise.get_future() }; - } - - std::suspend_never initial_suspend() const noexcept - { - return {}; - } - - std::suspend_never final_suspend() const noexcept - { - return {}; - } - - void return_void() noexcept - { - _promise.set_value(); - } - - void unhandled_exception() noexcept - { - _promise.set_exception(std::current_exception()); - } - - private: - std::promise _promise; - }; - - [[nodiscard("unexpected call")]] constexpr bool await_ready() const noexcept - { - return true; - } +namespace included = graphql::internal; - void await_suspend(std::coroutine_handle<> h) const - { - h.resume(); - } - - void await_resume() - { - _value.get(); - } +export namespace graphql::internal { -private: - std::future _value; -}; +namespace exported { template -class [[nodiscard("unnecessary construction")]] Awaitable -{ -public: - Awaitable(std::future value) - : _value { std::move(value) } - { - } - - [[nodiscard("unnecessary construction")]] T get() - { - return _value.get(); - } - - struct promise_type - { - [[nodiscard("unnecessary construction")]] Awaitable get_return_object() noexcept - { - return { _promise.get_future() }; - } - - std::suspend_never initial_suspend() const noexcept - { - return {}; - } - - std::suspend_never final_suspend() const noexcept - { - return {}; - } - - void return_value(const T& value) noexcept(std::is_nothrow_copy_constructible_v) - { - _promise.set_value(value); - } - - void return_value(T&& value) noexcept(std::is_nothrow_move_constructible_v) - { - _promise.set_value(std::move(value)); - } - - void unhandled_exception() noexcept - { - _promise.set_exception(std::current_exception()); - } - - private: - std::promise _promise; - }; - - [[nodiscard("unexpected call")]] constexpr bool await_ready() const noexcept - { - return true; - } - - void await_suspend(std::coroutine_handle<> h) const - { - h.resume(); - } +using Awaitable = included::Awaitable; - [[nodiscard("unnecessary construction")]] T await_resume() - { - return _value.get(); - } +} // namespace exported -private: - std::future _value; -}; +using namespace exported; } // namespace graphql::internal diff --git a/include/graphqlservice/internal/Base64.ixx b/include/graphqlservice/internal/Base64.ixx new file mode 100644 index 00000000..8fa6262d --- /dev/null +++ b/include/graphqlservice/internal/Base64.ixx @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Base64.h" + +export module GraphQL.Internal:Base64; + +namespace included = graphql::internal; + +export namespace graphql::internal { + +namespace exported { + +using Base64 = included::Base64; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::internal diff --git a/include/graphqlservice/internal/Grammar.ixx b/include/graphqlservice/internal/Grammar.ixx new file mode 100644 index 00000000..13752ead --- /dev/null +++ b/include/graphqlservice/internal/Grammar.ixx @@ -0,0 +1,287 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Grammar.h" + +export module GraphQL.Internal:Grammar; + +namespace included = graphql::peg; + +export namespace graphql::peg { + +namespace exported { + +using namespace tao::graphqlpeg; + +template +inline void for_each_child(const ast_node& n, std::function&& func) +{ + included::for_each_child(n, std::move(func)); +} + +template +inline void on_first_child_if(const ast_node& n, std::function&& func) +{ + included::on_first_child_if(n, std::move(func)); +} + +template +inline void on_first_child(const ast_node& n, std::function&& func) +{ + included::on_first_child(n, std::move(func)); +} + +using source_character = included::source_character; +using comment = included::comment; +using ignored = included::ignored; +using name = included::name; +using variable_name_content = included::variable_name_content; +using variable_name = included::variable_name; +using null_keyword = included::null_keyword; +using quote_token = included::quote_token; +using backslash_token = included::backslash_token; +using escaped_unicode_codepoint = included::escaped_unicode_codepoint; +using escaped_unicode_content = included::escaped_unicode_content; +using escaped_unicode = included::escaped_unicode; +using escaped_char = included::escaped_char; +using string_escape_sequence_content = included::string_escape_sequence_content; +using string_escape_sequence = included::string_escape_sequence; +using string_quote_character = included::string_quote_character; +using string_quote_content = included::string_quote_content; +using string_quote = included::string_quote; +using block_quote_token = included::block_quote_token; +using block_escape_sequence = included::block_escape_sequence; +using block_quote_character = included::block_quote_character; +using block_quote_empty_line = included::block_quote_empty_line; +using block_quote_line_content = included::block_quote_line_content; +using block_quote_line = included::block_quote_line; +using block_quote_content_lines = included::block_quote_content_lines; +using block_quote_content = included::block_quote_content; +using block_quote = included::block_quote; +using string_value = included::string_value; +using nonzero_digit = included::nonzero_digit; +using zero_digit = included::zero_digit; +using negative_sign = included::negative_sign; +using integer_part = included::integer_part; +using integer_value = included::integer_value; +using fractional_part_content = included::fractional_part_content; +using fractional_part = included::fractional_part; +using exponent_indicator = included::exponent_indicator; +using sign = included::sign; +using exponent_part_content = included::exponent_part_content; +using exponent_part = included::exponent_part; +using float_value = included::float_value; +using true_keyword = included::true_keyword; +using false_keyword = included::false_keyword; +using bool_value = included::bool_value; +using enum_value = included::enum_value; +using operation_type = included::operation_type; +using alias_name = included::alias_name; +using alias = included::alias; +using argument_name = included::argument_name; +using argument_content = included::argument_content; +using argument = included::argument; +using arguments_content = included::arguments_content; +using arguments = included::arguments; +using list_value_content = included::list_value_content; +using list_value = included::list_value; +using object_field_name = included::object_field_name; +using object_field_content = included::object_field_content; +using object_field = included::object_field; +using object_value_content = included::object_value_content; +using object_value = included::object_value; +using variable_value = included::variable_value; +using input_value_content = included::input_value_content; +using input_value = included::input_value; +using list_entry = included::list_entry; +using default_value_content = included::default_value_content; +using default_value = included::default_value; +using named_type = included::named_type; +using list_type_content = included::list_type_content; +using list_type = included::list_type; +using nonnull_type = included::nonnull_type; +using type_name_content = included::type_name_content; +using type_name = included::type_name; +using variable_content = included::variable_content; +using variable = included::variable; +using variable_definitions_content = included::variable_definitions_content; +using variable_definitions = included::variable_definitions; +using directive_name = included::directive_name; +using directive_content = included::directive_content; +using directive = included::directive; +using directives = included::directives; +using field_name = included::field_name; +using field_start = included::field_start; +using field_arguments = included::field_arguments; +using field_directives = included::field_directives; +using field_selection_set = included::field_selection_set; +using field_content = included::field_content; +using field = included::field; +using on_keyword = included::on_keyword; +using fragment_name = included::fragment_name; +using fragment_token = included::fragment_token; +using fragment_spread = included::fragment_spread; +using type_condition_content = included::type_condition_content; +using type_condition = included::type_condition; +using inline_fragment = included::inline_fragment; +using fragement_spread_or_inline_fragment_content = + included::fragement_spread_or_inline_fragment_content; +using fragement_spread_or_inline_fragment = included::fragement_spread_or_inline_fragment; +using selection = included::selection; +using selection_set_content = included::selection_set_content; +using selection_set = included::selection_set; +using operation_name = included::operation_name; +using operation_definition_operation_type_content = + included::operation_definition_operation_type_content; +using operation_definition = included::operation_definition; +using fragment_definition_content = included::fragment_definition_content; +using fragment_definition = included::fragment_definition; +using executable_definition = included::executable_definition; +using description = included::description; +using schema_keyword = included::schema_keyword; +using root_operation_definition_content = included::root_operation_definition_content; +using root_operation_definition = included::root_operation_definition; +using schema_definition_start = included::schema_definition_start; +using schema_definition_content = included::schema_definition_content; +using schema_definition = included::schema_definition; +using scalar_keyword = included::scalar_keyword; +using scalar_name = included::scalar_name; +using scalar_type_definition_start = included::scalar_type_definition_start; +using scalar_type_definition_content = included::scalar_type_definition_content; +using scalar_type_definition = included::scalar_type_definition; +using type_keyword = included::type_keyword; +using arguments_definition_start = included::arguments_definition_start; +using arguments_definition_content = included::arguments_definition_content; +using arguments_definition = included::arguments_definition; +using field_definition_start = included::field_definition_start; +using field_definition_content = included::field_definition_content; +using field_definition = included::field_definition; +using fields_definition_content = included::fields_definition_content; +using fields_definition = included::fields_definition; +using interface_type = included::interface_type; +using implements_interfaces_content = included::implements_interfaces_content; +using implements_interfaces = included::implements_interfaces; +using object_name = included::object_name; +using object_type_definition_start = included::object_type_definition_start; +using object_type_definition_object_name = included::object_type_definition_object_name; +using object_type_definition_implements_interfaces = + included::object_type_definition_implements_interfaces; +using object_type_definition_directives = included::object_type_definition_directives; +using object_type_definition_fields_definition = included::object_type_definition_fields_definition; +using object_type_definition_content = included::object_type_definition_content; +using object_type_definition = included::object_type_definition; +using interface_keyword = included::interface_keyword; +using interface_name = included::interface_name; +using interface_type_definition_start = included::interface_type_definition_start; +using interface_type_definition_interface_name = included::interface_type_definition_interface_name; +using interface_type_definition_implements_interfaces = + included::interface_type_definition_implements_interfaces; +using interface_type_definition_directives = included::interface_type_definition_directives; +using interface_type_definition_fields_definition = + included::interface_type_definition_fields_definition; +using interface_type_definition_content = included::interface_type_definition_content; +using interface_type_definition = included::interface_type_definition; +using union_keyword = included::union_keyword; +using union_name = included::union_name; +using union_type = included::union_type; +using union_member_types_start = included::union_member_types_start; +using union_member_types_content = included::union_member_types_content; +using union_member_types = included::union_member_types; +using union_type_definition_start = included::union_type_definition_start; +using union_type_definition_directives = included::union_type_definition_directives; +using union_type_definition_content = included::union_type_definition_content; +using union_type_definition = included::union_type_definition; +using enum_keyword = included::enum_keyword; +using enum_name = included::enum_name; +using enum_value_definition_start = included::enum_value_definition_start; +using enum_value_definition_content = included::enum_value_definition_content; +using enum_value_definition = included::enum_value_definition; +using enum_values_definition_start = included::enum_values_definition_start; +using enum_values_definition_content = included::enum_values_definition_content; +using enum_values_definition = included::enum_values_definition; +using enum_type_definition_start = included::enum_type_definition_start; +using enum_type_definition_name = included::enum_type_definition_name; +using enum_type_definition_directives = included::enum_type_definition_directives; +using enum_type_definition_enum_values_definition = + included::enum_type_definition_enum_values_definition; +using enum_type_definition_content = included::enum_type_definition_content; +using enum_type_definition = included::enum_type_definition; +using input_keyword = included::input_keyword; +using input_field_definition_start = included::input_field_definition_start; +using input_field_definition_type_name = included::input_field_definition_type_name; +using input_field_definition_default_value = included::input_field_definition_default_value; +using input_field_definition_directives = included::input_field_definition_directives; +using input_field_definition_content = included::input_field_definition_content; +using input_field_definition = included::input_field_definition; +using input_fields_definition_start = included::input_fields_definition_start; +using input_fields_definition_content = included::input_fields_definition_content; +using input_fields_definition = included::input_fields_definition; +using input_object_type_definition_start = included::input_object_type_definition_start; +using input_object_type_definition_object_name = included::input_object_type_definition_object_name; +using input_object_type_definition_directives = included::input_object_type_definition_directives; +using input_object_type_definition_fields_definition = + included::input_object_type_definition_fields_definition; +using input_object_type_definition_content = included::input_object_type_definition_content; +using input_object_type_definition = included::input_object_type_definition; +using type_definition = included::type_definition; +using executable_directive_location = included::executable_directive_location; +using type_system_directive_location = included::type_system_directive_location; +using directive_location = included::directive_location; +using directive_locations = included::directive_locations; +using directive_definition_start = included::directive_definition_start; +using repeatable_keyword = included::repeatable_keyword; +using directive_definition_content = included::directive_definition_content; +using directive_definition = included::directive_definition; +using type_system_definition = included::type_system_definition; +using extend_keyword = included::extend_keyword; +using operation_type_definition = included::operation_type_definition; +using schema_extension_start = included::schema_extension_start; +using schema_extension_operation_type_definitions = + included::schema_extension_operation_type_definitions; +using schema_extension_content = included::schema_extension_content; +using schema_extension = included::schema_extension; +using scalar_type_extension_start = included::scalar_type_extension_start; +using scalar_type_extension_content = included::scalar_type_extension_content; +using scalar_type_extension = included::scalar_type_extension; +using object_type_extension_start = included::object_type_extension_start; +using object_type_extension_implements_interfaces = + included::object_type_extension_implements_interfaces; +using object_type_extension_directives = included::object_type_extension_directives; +using object_type_extension_fields_definition = included::object_type_extension_fields_definition; +using object_type_extension_content = included::object_type_extension_content; +using object_type_extension = included::object_type_extension; +using interface_type_extension_start = included::interface_type_extension_start; +using interface_type_extension_implements_interfaces = + included::interface_type_extension_implements_interfaces; +using interface_type_extension_directives = included::interface_type_extension_directives; +using interface_type_extension_fields_definition = + included::interface_type_extension_fields_definition; +using interface_type_extension_content = included::interface_type_extension_content; +using interface_type_extension = included::interface_type_extension; +using union_type_extension_start = included::union_type_extension_start; +using union_type_extension_content = included::union_type_extension_content; +using union_type_extension = included::union_type_extension; +using enum_type_extension_start = included::enum_type_extension_start; +using enum_type_extension_content = included::enum_type_extension_content; +using enum_type_extension = included::enum_type_extension; +using input_object_type_extension_start = included::input_object_type_extension_start; +using input_object_type_extension_content = included::input_object_type_extension_content; +using input_object_type_extension = included::input_object_type_extension; +using type_extension = included::type_extension; +using type_system_extension = included::type_system_extension; +using mixed_definition = included::mixed_definition; +using mixed_document_content = included::mixed_document_content; +using mixed_document = included::mixed_document; +using executable_document_content = included::executable_document_content; +using executable_document = included::executable_document; +using schema_type_definition = included::schema_type_definition; +using schema_document_content = included::schema_document_content; +using schema_document = included::schema_document; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::peg diff --git a/include/graphqlservice/internal/Introspection.ixx b/include/graphqlservice/internal/Introspection.ixx new file mode 100644 index 00000000..5c6b4541 --- /dev/null +++ b/include/graphqlservice/internal/Introspection.ixx @@ -0,0 +1,102 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Introspection.h" + +export module GraphQL.Internal:Introspection; + +namespace included = graphql::introspection; + +export namespace graphql::introspection { + +namespace object { + +namespace exported { + +using Schema = included::object::Schema; +using Type = included::object::Type; +using Field = included::object::Field; +using InputValue = included::object::InputValue; +using EnumValue = included::object::EnumValue; +using Directive = included::object::Directive; + +} // namespace exported + +using namespace exported; + +} // namespace object + +namespace exported { + +using TypeKind = included::TypeKind; + +constexpr auto getTypeKindNames() noexcept +{ + return included::getTypeKindNames(); +} + +constexpr auto getTypeKindValues() noexcept +{ + return included::getTypeKindValues(); +} + +using DirectiveLocation = included::DirectiveLocation; + +constexpr auto getDirectiveLocationNames() noexcept +{ + return included::getDirectiveLocationNames(); +} + +constexpr auto getDirectiveLocationValues() noexcept +{ + return included::getDirectiveLocationValues(); +} + +using Schema = included::Schema; +using Type = included::Type; +using Field = included::Field; +using InputValue = included::InputValue; +using EnumValue = included::EnumValue; +using Directive = included::Directive; + +void AddSchemaDetails(const std::shared_ptr& typeSchema, const std::shared_ptr& schema) +{ + included::AddSchemaDetails(typeSchema, schema); +} + +void AddTypeDetails(const std::shared_ptr& typeType, const std::shared_ptr& schema) +{ + included::AddTypeDetails(typeType, schema); +} + +void AddFieldDetails(const std::shared_ptr& typeField, const std::shared_ptr& schema) +{ + included::AddFieldDetails(typeField, schema); +} + +void AddInputValueDetails(const std::shared_ptr& typeInputValue, const std::shared_ptr& schema) +{ + included::AddInputValueDetails(typeInputValue, schema); +} + +void AddEnumValueDetails(const std::shared_ptr& typeEnumValue, const std::shared_ptr& schema) +{ + included::AddEnumValueDetails(typeEnumValue, schema); +} + +void AddDirectiveDetails(const std::shared_ptr& typeDirective, const std::shared_ptr& schema) +{ + included::AddDirectiveDetails(typeDirective, schema); +} + +void AddTypesToSchema(const std::shared_ptr& schema){ + included::AddTypesToSchema(schema); +} + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection diff --git a/include/graphqlservice/internal/Schema.ixx b/include/graphqlservice/internal/Schema.ixx new file mode 100644 index 00000000..14c2f849 --- /dev/null +++ b/include/graphqlservice/internal/Schema.ixx @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Schema.h" + +export module GraphQL.Internal:Schema; + +namespace included { + +namespace introspection = graphql::introspection; +namespace schema = graphql::schema; + +} // namespace included + +export namespace graphql { + +namespace introspection { + +namespace exported { + +using TypeKind = included::introspection::TypeKind; +using DirectiveLocation = included::introspection::DirectiveLocation; + +} // namespace exported + +using namespace exported; + +} // namespace introspection + +namespace schema { + +namespace exported { + +using Schema = included::schema::Schema; +using BaseType = included::schema::BaseType; +using ScalarType = included::schema::ScalarType; +using ObjectType = included::schema::ObjectType; +using InterfaceType = included::schema::InterfaceType; +using UnionType = included::schema::UnionType; +using EnumValueType = included::schema::EnumValueType; +using EnumType = included::schema::EnumType; +using InputObjectType = included::schema::InputObjectType; +using WrapperType = included::schema::WrapperType; +using Field = included::schema::Field; +using InputValue = included::schema::InputValue; +using EnumValue = included::schema::EnumValue; +using Directive = included::schema::Directive; + +} // namespace exported + +using namespace exported; + +} // namespace schema + +} // namespace graphql diff --git a/include/graphqlservice/internal/SortedMap.ixx b/include/graphqlservice/internal/SortedMap.ixx new file mode 100644 index 00000000..505c9936 --- /dev/null +++ b/include/graphqlservice/internal/SortedMap.ixx @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "SortedMap.h" + +export module GraphQL.Internal:SortedMap; + +namespace included = graphql::internal; + +export namespace graphql::internal { + +namespace exported { + +template +using sorted_map_key = included::sorted_map_key; + +template ()->second)> +[[nodiscard("unnecessary call")]] constexpr std::pair sorted_map_equal_range( + Iterator itrBegin, Iterator itrEnd, K&& key) noexcept +{ + return included::sorted_map_equal_range(itrBegin, itrEnd, std::forward(key)); +} + +template +[[nodiscard("unnecessary call")]] constexpr auto sorted_map_lookup( + const Container& container, K&& key) noexcept +{ + return included::sorted_map_lookup(container, std::forward(key)); +} + +template > +using sorted_map = included::sorted_map; + +template > +using sorted_set = included::sorted_set; + +using shorter_or_less = included::shorter_or_less; + +template +using string_view_map = included::string_view_map; + +using string_view_set = included::string_view_set; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::internal diff --git a/include/graphqlservice/internal/SyntaxTree.ixx b/include/graphqlservice/internal/SyntaxTree.ixx new file mode 100644 index 00000000..571bb783 --- /dev/null +++ b/include/graphqlservice/internal/SyntaxTree.ixx @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "SyntaxTree.h" + +export module GraphQL.Internal:SyntaxTree; + +export namespace graphql::peg { + +namespace exported { + +using namespace tao::graphqlpeg; +namespace peginternal = tao::graphqlpeg::internal; + +using ast_node = graphql::peg::ast_node; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::peg diff --git a/include/graphqlservice/internal/Version.ixx b/include/graphqlservice/internal/Version.ixx index c4769603..997b8a2f 100644 --- a/include/graphqlservice/internal/Version.ixx +++ b/include/graphqlservice/internal/Version.ixx @@ -5,7 +5,7 @@ module; #include "Version.h" -export module Internal.Version; +export module GraphQL.Internal:Version; export namespace graphql::internal { diff --git a/include/graphqlservice/introspection/IntrospectionSchema.h b/include/graphqlservice/introspection/IntrospectionSchema.h index eba4825d..b8e76fe3 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.h +++ b/include/graphqlservice/introspection/IntrospectionSchema.h @@ -11,6 +11,7 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" #include @@ -18,8 +19,6 @@ #include #include -import Internal.Version; - // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/samples/client/benchmark/BenchmarkClient.h b/samples/client/benchmark/BenchmarkClient.h index daf02ef3..9ba57395 100644 --- a/samples/client/benchmark/BenchmarkClient.h +++ b/samples/client/benchmark/BenchmarkClient.h @@ -12,12 +12,12 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/internal/Version.h" + #include #include #include -import Internal.Version; - // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); diff --git a/samples/client/multiple/MultipleQueriesClient.h b/samples/client/multiple/MultipleQueriesClient.h index 3b5f7efb..e57ad66d 100644 --- a/samples/client/multiple/MultipleQueriesClient.h +++ b/samples/client/multiple/MultipleQueriesClient.h @@ -12,12 +12,12 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/internal/Version.h" + #include #include #include -import Internal.Version; - // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); diff --git a/samples/client/mutate/MutateClient.h b/samples/client/mutate/MutateClient.h index 8e862ab7..2fbe3a4a 100644 --- a/samples/client/mutate/MutateClient.h +++ b/samples/client/mutate/MutateClient.h @@ -12,12 +12,12 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/internal/Version.h" + #include #include #include -import Internal.Version; - // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); diff --git a/samples/client/nestedinput/NestedInputClient.h b/samples/client/nestedinput/NestedInputClient.h index b914cad6..d3dd2db2 100644 --- a/samples/client/nestedinput/NestedInputClient.h +++ b/samples/client/nestedinput/NestedInputClient.h @@ -12,12 +12,12 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/internal/Version.h" + #include #include #include -import Internal.Version; - // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); diff --git a/samples/client/query/QueryClient.h b/samples/client/query/QueryClient.h index 7953c0dc..109ddf5c 100644 --- a/samples/client/query/QueryClient.h +++ b/samples/client/query/QueryClient.h @@ -12,12 +12,12 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/internal/Version.h" + #include #include #include -import Internal.Version; - // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); diff --git a/samples/client/subscribe/SubscribeClient.h b/samples/client/subscribe/SubscribeClient.h index 3f841a0e..e01d433e 100644 --- a/samples/client/subscribe/SubscribeClient.h +++ b/samples/client/subscribe/SubscribeClient.h @@ -12,12 +12,12 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/internal/Version.h" + #include #include #include -import Internal.Version; - // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); diff --git a/samples/learn/schema/StarWarsSchema.h b/samples/learn/schema/StarWarsSchema.h index b62f53da..43d229b4 100644 --- a/samples/learn/schema/StarWarsSchema.h +++ b/samples/learn/schema/StarWarsSchema.h @@ -11,6 +11,7 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" #include @@ -18,8 +19,6 @@ #include #include -import Internal.Version; - // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/samples/proxy/query/ProxyClient.h b/samples/proxy/query/ProxyClient.h index 5ff9c4e6..6301f8e6 100644 --- a/samples/proxy/query/ProxyClient.h +++ b/samples/proxy/query/ProxyClient.h @@ -12,12 +12,12 @@ #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/internal/Version.h" + #include #include #include -import Internal.Version; - // Check if the library version is compatible with clientgen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); diff --git a/samples/proxy/schema/ProxySchema.h b/samples/proxy/schema/ProxySchema.h index c6100aa5..dbf732ba 100644 --- a/samples/proxy/schema/ProxySchema.h +++ b/samples/proxy/schema/ProxySchema.h @@ -11,6 +11,7 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" #include @@ -18,8 +19,6 @@ #include #include -import Internal.Version; - // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/samples/today/nointrospection/TodaySchema.h b/samples/today/nointrospection/TodaySchema.h index 89d700ab..8128495e 100644 --- a/samples/today/nointrospection/TodaySchema.h +++ b/samples/today/nointrospection/TodaySchema.h @@ -11,6 +11,7 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" #include @@ -18,8 +19,6 @@ #include #include -import Internal.Version; - // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/samples/today/schema/TodaySchema.h b/samples/today/schema/TodaySchema.h index 89d700ab..8128495e 100644 --- a/samples/today/schema/TodaySchema.h +++ b/samples/today/schema/TodaySchema.h @@ -11,6 +11,7 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" #include @@ -18,8 +19,6 @@ #include #include -import Internal.Version; - // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/samples/validation/schema/ValidationSchema.h b/samples/validation/schema/ValidationSchema.h index 8e410b6d..980bba28 100644 --- a/samples/validation/schema/ValidationSchema.h +++ b/samples/validation/schema/ValidationSchema.h @@ -11,6 +11,7 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" #include @@ -18,8 +19,6 @@ #include #include -import Internal.Version; - // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9060a20e..3d49a097 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -73,15 +73,28 @@ endfunction() file(REAL_PATH ../include/ INCLUDE_ROOT) -# graphqlawaitable -add_library(graphqlawaitable STATIC) -add_library(cppgraphqlgen::graphqlawaitable ALIAS graphqlawaitable) -target_compile_features(graphqlawaitable PUBLIC cxx_std_20) -target_sources(graphqlawaitable PUBLIC FILE_SET CXX_MODULES +# graphql_internal_module +add_library(graphql_internal_module STATIC) +add_library(cppgraphqlgen::graphql_internal_module ALIAS graphql_internal_module) +target_compile_features(graphql_internal_module PUBLIC cxx_std_20) +target_link_libraries(graphql_internal_module PUBLIC taocpp::pegtl) +target_include_directories(graphql_internal_module PUBLIC + $ + $ + $) +target_sources(graphql_internal_module PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${INCLUDE_ROOT} FILES - ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.ixx) + ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Base64.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Schema.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx + ${INCLUDE_ROOT}/graphqlservice/GraphQL.Internal.ixx) function(check_coroutine_impl OPTIONAL_FLAGS OUT_RESULT) set(TEST_FILE "test_coroutine.cpp") @@ -103,7 +116,7 @@ function(check_coroutine_impl OPTIONAL_FLAGS OUT_RESULT) if(TEST_RESULT) # Looks like the optional flag was required, go ahead and add it to the compile options. - target_compile_options(graphqlawaitable INTERFACE ${OPTIONAL_FLAG}) + target_compile_options(graphql_internal_module INTERFACE ${OPTIONAL_FLAG}) break() endif() endforeach(OPTIONAL_FLAG) @@ -161,7 +174,7 @@ target_compile_features(graphqlresponse PUBLIC cxx_std_20) target_include_directories(graphqlresponse PUBLIC $ $) -target_link_libraries(graphqlresponse PUBLIC graphqlawaitable) +target_link_libraries(graphqlresponse PUBLIC graphql_internal_module) if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqlresponse) @@ -347,7 +360,7 @@ add_library(cppgraphqlgen::graphqlservice ALIAS graphqlservice) target_compile_features(graphqlservice PUBLIC cxx_std_20) target_link_libraries(graphqlservice PUBLIC graphqlversion - graphqlawaitable + graphql_internal_module graphqlpeg graphqlresponse Threads::Threads) @@ -423,7 +436,7 @@ if(GRAPHQL_USE_RAPIDJSON) endif() install(TARGETS - graphqlawaitable + graphql_internal_module graphqlversion graphqlclient graphqlpeg diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 40abe947..1c3f43d0 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -4,6 +4,7 @@ #include "ClientGenerator.h" #include "GeneratorUtil.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/introspection/IntrospectionSchema.h" #ifdef _MSC_VER @@ -26,8 +27,6 @@ #include #include -import Internal.Version; - using namespace std::literals; namespace graphql::generator::client { @@ -174,12 +173,12 @@ bool Generator::outputHeader() const noexcept #include "graphqlservice/GraphQLParse.h" #include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/internal/Version.h" + #include #include #include -import Internal.Version; - // Check if the library version is compatible with clientgen )cpp" << graphql::internal::MajorVersion << R"cpp(.)cpp" << graphql::internal::MinorVersion << R"cpp(.0 diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 9cd1ebbd..ad376c62 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -4,6 +4,8 @@ #include "SchemaGenerator.h" #include "GeneratorUtil.h" +#include "graphqlservice/internal/Version.h" + #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 26495) @@ -26,8 +28,6 @@ #include #include -import Internal.Version; - using namespace std::literals; namespace graphql::generator::schema { @@ -115,6 +115,7 @@ bool Generator::outputHeader() const noexcept headerFile << R"cpp(#include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" #include @@ -122,8 +123,6 @@ bool Generator::outputHeader() const noexcept #include #include -import Internal.Version; - // Check if the library version is compatible with schemagen )cpp" << graphql::internal::MajorVersion << R"cpp(.)cpp" << graphql::internal::MinorVersion << R"cpp(.0 diff --git a/src/introspection/IntrospectionSchema.h b/src/introspection/IntrospectionSchema.h index eba4825d..b8e76fe3 100644 --- a/src/introspection/IntrospectionSchema.h +++ b/src/introspection/IntrospectionSchema.h @@ -11,6 +11,7 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" #include @@ -18,8 +19,6 @@ #include #include -import Internal.Version; - // Check if the library version is compatible with schemagen 4.5.0 static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); From 7e8d6f81fe1cafaee836a08d841870b9404bdd87 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 21:29:13 -0700 Subject: [PATCH 027/123] chore(cmake): install headers and module interfaces together --- src/CMakeLists.txt | 72 +++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3d49a097..2fdbfc17 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -82,19 +82,32 @@ target_include_directories(graphql_internal_module PUBLIC $ $ $) -target_sources(graphql_internal_module PUBLIC FILE_SET CXX_MODULES -BASE_DIRS - ${INCLUDE_ROOT} -FILES - ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Base64.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Schema.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx - ${INCLUDE_ROOT}/graphqlservice/GraphQL.Internal.ixx) +target_sources(graphql_internal_module + PUBLIC FILE_SET HEADERS + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.h + ${INCLUDE_ROOT}/graphqlservice/internal/Base64.h + ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.h + ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.h + ${INCLUDE_ROOT}/graphqlservice/internal/Schema.h + ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.h + ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.h + ${INCLUDE_ROOT}/graphqlservice/internal/Version.h + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Base64.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Schema.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx + ${INCLUDE_ROOT}/graphqlservice/GraphQL.Internal.ixx) function(check_coroutine_impl OPTIONAL_FLAGS OUT_RESULT) set(TEST_FILE "test_coroutine.cpp") @@ -132,16 +145,6 @@ else() message(FATAL_ERROR "Missing coroutine support") endif() -# graphqlversion -add_library(graphqlversion STATIC) -add_library(cppgraphqlgen::graphqlversion ALIAS graphqlversion) -target_compile_features(graphqlversion PUBLIC cxx_std_20) -target_sources(graphqlversion PUBLIC FILE_SET CXX_MODULES -BASE_DIRS - ${INCLUDE_ROOT} -FILES - ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx) - # graphqlpeg add_library(graphqlpeg SyntaxTree.cpp) add_library(cppgraphqlgen::graphqlpeg ALIAS graphqlpeg) @@ -196,7 +199,6 @@ if(GRAPHQL_BUILD_SCHEMAGEN OR GRAPHQL_BUILD_CLIENTGEN) GeneratorUtil.cpp) target_compile_features(generator_util PUBLIC cxx_std_20) target_link_libraries(generator_util PUBLIC - graphqlversion graphqlpeg graphqlresponse) endif() @@ -359,7 +361,6 @@ add_library(graphqlservice add_library(cppgraphqlgen::graphqlservice ALIAS graphqlservice) target_compile_features(graphqlservice PUBLIC cxx_std_20) target_link_libraries(graphqlservice PUBLIC - graphqlversion graphql_internal_module graphqlpeg graphqlresponse @@ -390,7 +391,6 @@ add_library(graphqlclient GraphQLClient.cpp) add_library(cppgraphqlgen::graphqlclient ALIAS graphqlclient) target_compile_features(graphqlclient PUBLIC cxx_std_20) target_link_libraries(graphqlclient PUBLIC - graphqlversion graphqlpeg graphqlresponse) @@ -437,7 +437,6 @@ endif() install(TARGETS graphql_internal_module - graphqlversion graphqlclient graphqlpeg graphqlresponse @@ -446,7 +445,12 @@ install(TARGETS RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib - FILE_SET CXX_MODULES DESTINATION include) + FILE_SET HEADERS + CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} + DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR} + FILE_SET CXX_MODULES + CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} + DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/GraphQLClient.h @@ -456,18 +460,6 @@ install(FILES CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}/graphqlservice) -install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Awaitable.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Base64.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Grammar.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Introspection.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Schema.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/SortedMap.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/SyntaxTree.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Version.h - CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} - DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}/graphqlservice/internal) - # graphqljson if(BUILD_GRAPHQLJSON) target_link_libraries(graphqljson PUBLIC graphqlresponse) From bf6b48d95609418ab683deeedb310e910875485f Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 21:48:56 -0700 Subject: [PATCH 028/123] chore(modules): move primary interface to internal/Module.ixx --- .../{GraphQL.Internal.ixx => internal/Module.ixx} | 0 src/CMakeLists.txt | 6 ++---- 2 files changed, 2 insertions(+), 4 deletions(-) rename include/graphqlservice/{GraphQL.Internal.ixx => internal/Module.ixx} (100%) diff --git a/include/graphqlservice/GraphQL.Internal.ixx b/include/graphqlservice/internal/Module.ixx similarity index 100% rename from include/graphqlservice/GraphQL.Internal.ixx rename to include/graphqlservice/internal/Module.ixx diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2fdbfc17..8c5c4e37 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -80,7 +80,6 @@ target_compile_features(graphql_internal_module PUBLIC cxx_std_20) target_link_libraries(graphql_internal_module PUBLIC taocpp::pegtl) target_include_directories(graphql_internal_module PUBLIC $ - $ $) target_sources(graphql_internal_module PUBLIC FILE_SET HEADERS @@ -103,11 +102,11 @@ target_sources(graphql_internal_module ${INCLUDE_ROOT}/graphqlservice/internal/Base64.ixx ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.ixx ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Module.ixx ${INCLUDE_ROOT}/graphqlservice/internal/Schema.ixx ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.ixx ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx - ${INCLUDE_ROOT}/graphqlservice/GraphQL.Internal.ixx) + ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx) function(check_coroutine_impl OPTIONAL_FLAGS OUT_RESULT) set(TEST_FILE "test_coroutine.cpp") @@ -152,7 +151,6 @@ target_compile_features(graphqlpeg PUBLIC cxx_std_20) target_link_libraries(graphqlpeg PUBLIC taocpp::pegtl) target_include_directories(graphqlpeg PUBLIC $ - $ $) add_bigobj_flag(graphqlpeg) From 5980cb9de04e89ec682732e98e332f25f02b37df Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 21:59:09 -0700 Subject: [PATCH 029/123] fix(modules): separate modules instead of partitioning for ICE --- include/graphqlservice/internal/Awaitable.ixx | 2 +- include/graphqlservice/internal/Base64.ixx | 2 +- include/graphqlservice/internal/Grammar.ixx | 2 +- .../graphqlservice/internal/Introspection.ixx | 2 +- include/graphqlservice/internal/Module.ixx | 16 ++++++++-------- include/graphqlservice/internal/Schema.ixx | 2 +- include/graphqlservice/internal/SortedMap.ixx | 2 +- include/graphqlservice/internal/SyntaxTree.ixx | 2 +- include/graphqlservice/internal/Version.ixx | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/graphqlservice/internal/Awaitable.ixx b/include/graphqlservice/internal/Awaitable.ixx index 261399e4..052f52f0 100644 --- a/include/graphqlservice/internal/Awaitable.ixx +++ b/include/graphqlservice/internal/Awaitable.ixx @@ -5,7 +5,7 @@ module; #include "Awaitable.h" -export module GraphQL.Internal:Awaitable; +export module GraphQL.Internal.Awaitable; namespace included = graphql::internal; diff --git a/include/graphqlservice/internal/Base64.ixx b/include/graphqlservice/internal/Base64.ixx index 8fa6262d..067bd14e 100644 --- a/include/graphqlservice/internal/Base64.ixx +++ b/include/graphqlservice/internal/Base64.ixx @@ -5,7 +5,7 @@ module; #include "Base64.h" -export module GraphQL.Internal:Base64; +export module GraphQL.Internal.Base64; namespace included = graphql::internal; diff --git a/include/graphqlservice/internal/Grammar.ixx b/include/graphqlservice/internal/Grammar.ixx index 13752ead..9ca69005 100644 --- a/include/graphqlservice/internal/Grammar.ixx +++ b/include/graphqlservice/internal/Grammar.ixx @@ -5,7 +5,7 @@ module; #include "Grammar.h" -export module GraphQL.Internal:Grammar; +export module GraphQL.Internal.Grammar; namespace included = graphql::peg; diff --git a/include/graphqlservice/internal/Introspection.ixx b/include/graphqlservice/internal/Introspection.ixx index 5c6b4541..b1bc27f7 100644 --- a/include/graphqlservice/internal/Introspection.ixx +++ b/include/graphqlservice/internal/Introspection.ixx @@ -5,7 +5,7 @@ module; #include "Introspection.h" -export module GraphQL.Internal:Introspection; +export module GraphQL.Internal.Introspection; namespace included = graphql::introspection; diff --git a/include/graphqlservice/internal/Module.ixx b/include/graphqlservice/internal/Module.ixx index c0e84699..b33d2d27 100644 --- a/include/graphqlservice/internal/Module.ixx +++ b/include/graphqlservice/internal/Module.ixx @@ -3,11 +3,11 @@ export module GraphQL.Internal; -export import :Awaitable; -export import :Base64; -export import :Grammar; -export import :Introspection; -export import :Schema; -export import :SortedMap; -export import :SyntaxTree; -export import :Version; +export import GraphQL.Internal.Awaitable; +export import GraphQL.Internal.Base64; +export import GraphQL.Internal.Grammar; +export import GraphQL.Internal.Introspection; +export import GraphQL.Internal.Schema; +export import GraphQL.Internal.SortedMap; +export import GraphQL.Internal.SyntaxTree; +export import GraphQL.Internal.Version; diff --git a/include/graphqlservice/internal/Schema.ixx b/include/graphqlservice/internal/Schema.ixx index 14c2f849..d52f8880 100644 --- a/include/graphqlservice/internal/Schema.ixx +++ b/include/graphqlservice/internal/Schema.ixx @@ -5,7 +5,7 @@ module; #include "Schema.h" -export module GraphQL.Internal:Schema; +export module GraphQL.Internal.Schema; namespace included { diff --git a/include/graphqlservice/internal/SortedMap.ixx b/include/graphqlservice/internal/SortedMap.ixx index 505c9936..d0719481 100644 --- a/include/graphqlservice/internal/SortedMap.ixx +++ b/include/graphqlservice/internal/SortedMap.ixx @@ -5,7 +5,7 @@ module; #include "SortedMap.h" -export module GraphQL.Internal:SortedMap; +export module GraphQL.Internal.SortedMap; namespace included = graphql::internal; diff --git a/include/graphqlservice/internal/SyntaxTree.ixx b/include/graphqlservice/internal/SyntaxTree.ixx index 571bb783..89127a32 100644 --- a/include/graphqlservice/internal/SyntaxTree.ixx +++ b/include/graphqlservice/internal/SyntaxTree.ixx @@ -5,7 +5,7 @@ module; #include "SyntaxTree.h" -export module GraphQL.Internal:SyntaxTree; +export module GraphQL.Internal.SyntaxTree; export namespace graphql::peg { diff --git a/include/graphqlservice/internal/Version.ixx b/include/graphqlservice/internal/Version.ixx index 997b8a2f..86bf0cd5 100644 --- a/include/graphqlservice/internal/Version.ixx +++ b/include/graphqlservice/internal/Version.ixx @@ -5,7 +5,7 @@ module; #include "Version.h" -export module GraphQL.Internal:Version; +export module GraphQL.Internal.Version; export namespace graphql::internal { From 4d9c8742003c13bab01326272491700783476e7c Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 22:09:33 -0700 Subject: [PATCH 030/123] fix(modules): re-exporting all of the modules together seems to be what causes ICE --- include/graphqlservice/internal/Module.ixx | 13 ------------- src/CMakeLists.txt | 1 - 2 files changed, 14 deletions(-) delete mode 100644 include/graphqlservice/internal/Module.ixx diff --git a/include/graphqlservice/internal/Module.ixx b/include/graphqlservice/internal/Module.ixx deleted file mode 100644 index b33d2d27..00000000 --- a/include/graphqlservice/internal/Module.ixx +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -export module GraphQL.Internal; - -export import GraphQL.Internal.Awaitable; -export import GraphQL.Internal.Base64; -export import GraphQL.Internal.Grammar; -export import GraphQL.Internal.Introspection; -export import GraphQL.Internal.Schema; -export import GraphQL.Internal.SortedMap; -export import GraphQL.Internal.SyntaxTree; -export import GraphQL.Internal.Version; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8c5c4e37..8de9ff6e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -102,7 +102,6 @@ target_sources(graphql_internal_module ${INCLUDE_ROOT}/graphqlservice/internal/Base64.ixx ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.ixx ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Module.ixx ${INCLUDE_ROOT}/graphqlservice/internal/Schema.ixx ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.ixx ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.ixx From f45e744d7879b65788c374b8f579e338c6628b8e Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 12 Sep 2024 23:18:27 -0700 Subject: [PATCH 031/123] fix(modules): add interface modules for include/graphqlservice/introspection --- .../graphqlservice/internal/Introspection.ixx | 75 ---------------- .../introspection/DirectiveObject.ixx | 24 ++++++ .../introspection/EnumValueObject.ixx | 24 ++++++ .../introspection/FieldObject.ixx | 24 ++++++ .../introspection/InputValueObject.ixx | 24 ++++++ .../introspection/IntrospectionSchema.ixx | 85 +++++++++++++++++++ .../introspection/SchemaObject.ixx | 24 ++++++ .../introspection/TypeObject.ixx | 24 ++++++ src/CMakeLists.txt | 46 +++++++--- src/introspection/CMakeLists.txt | 5 -- 10 files changed, 264 insertions(+), 91 deletions(-) create mode 100644 include/graphqlservice/introspection/DirectiveObject.ixx create mode 100644 include/graphqlservice/introspection/EnumValueObject.ixx create mode 100644 include/graphqlservice/introspection/FieldObject.ixx create mode 100644 include/graphqlservice/introspection/InputValueObject.ixx create mode 100644 include/graphqlservice/introspection/IntrospectionSchema.ixx create mode 100644 include/graphqlservice/introspection/SchemaObject.ixx create mode 100644 include/graphqlservice/introspection/TypeObject.ixx diff --git a/include/graphqlservice/internal/Introspection.ixx b/include/graphqlservice/internal/Introspection.ixx index b1bc27f7..4bb0d634 100644 --- a/include/graphqlservice/internal/Introspection.ixx +++ b/include/graphqlservice/internal/Introspection.ixx @@ -11,49 +11,8 @@ namespace included = graphql::introspection; export namespace graphql::introspection { -namespace object { - namespace exported { -using Schema = included::object::Schema; -using Type = included::object::Type; -using Field = included::object::Field; -using InputValue = included::object::InputValue; -using EnumValue = included::object::EnumValue; -using Directive = included::object::Directive; - -} // namespace exported - -using namespace exported; - -} // namespace object - -namespace exported { - -using TypeKind = included::TypeKind; - -constexpr auto getTypeKindNames() noexcept -{ - return included::getTypeKindNames(); -} - -constexpr auto getTypeKindValues() noexcept -{ - return included::getTypeKindValues(); -} - -using DirectiveLocation = included::DirectiveLocation; - -constexpr auto getDirectiveLocationNames() noexcept -{ - return included::getDirectiveLocationNames(); -} - -constexpr auto getDirectiveLocationValues() noexcept -{ - return included::getDirectiveLocationValues(); -} - using Schema = included::Schema; using Type = included::Type; using Field = included::Field; @@ -61,40 +20,6 @@ using InputValue = included::InputValue; using EnumValue = included::EnumValue; using Directive = included::Directive; -void AddSchemaDetails(const std::shared_ptr& typeSchema, const std::shared_ptr& schema) -{ - included::AddSchemaDetails(typeSchema, schema); -} - -void AddTypeDetails(const std::shared_ptr& typeType, const std::shared_ptr& schema) -{ - included::AddTypeDetails(typeType, schema); -} - -void AddFieldDetails(const std::shared_ptr& typeField, const std::shared_ptr& schema) -{ - included::AddFieldDetails(typeField, schema); -} - -void AddInputValueDetails(const std::shared_ptr& typeInputValue, const std::shared_ptr& schema) -{ - included::AddInputValueDetails(typeInputValue, schema); -} - -void AddEnumValueDetails(const std::shared_ptr& typeEnumValue, const std::shared_ptr& schema) -{ - included::AddEnumValueDetails(typeEnumValue, schema); -} - -void AddDirectiveDetails(const std::shared_ptr& typeDirective, const std::shared_ptr& schema) -{ - included::AddDirectiveDetails(typeDirective, schema); -} - -void AddTypesToSchema(const std::shared_ptr& schema){ - included::AddTypesToSchema(schema); -} - } // namespace exported using namespace exported; diff --git a/include/graphqlservice/introspection/DirectiveObject.ixx b/include/graphqlservice/introspection/DirectiveObject.ixx new file mode 100644 index 00000000..3074c61c --- /dev/null +++ b/include/graphqlservice/introspection/DirectiveObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "DirectiveObject.h" + +export module GraphQL.Introspection.DirectiveObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using Directive = included::Directive; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/EnumValueObject.ixx b/include/graphqlservice/introspection/EnumValueObject.ixx new file mode 100644 index 00000000..3fe1aac9 --- /dev/null +++ b/include/graphqlservice/introspection/EnumValueObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "EnumValueObject.h" + +export module GraphQL.Introspection.EnumValueObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using EnumValue = included::EnumValue; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/FieldObject.ixx b/include/graphqlservice/introspection/FieldObject.ixx new file mode 100644 index 00000000..6458133e --- /dev/null +++ b/include/graphqlservice/introspection/FieldObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FieldObject.h" + +export module GraphQL.Introspection.FieldObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using Field = included::Field; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/InputValueObject.ixx b/include/graphqlservice/introspection/InputValueObject.ixx new file mode 100644 index 00000000..ffa0ce4e --- /dev/null +++ b/include/graphqlservice/introspection/InputValueObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "InputValueObject.h" + +export module GraphQL.Introspection.InputValueObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using InputValue = included::InputValue; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/IntrospectionSchema.ixx b/include/graphqlservice/introspection/IntrospectionSchema.ixx new file mode 100644 index 00000000..c6f6c791 --- /dev/null +++ b/include/graphqlservice/introspection/IntrospectionSchema.ixx @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "IntrospectionSchema.h" + +export module GraphQL.Introspection.IntrospectionSchema; + +namespace included = graphql::introspection; + +export namespace graphql::introspection { + +namespace exported { + +using TypeKind = included::TypeKind; + +constexpr auto getTypeKindNames() noexcept +{ + return included::getTypeKindNames(); +} + +constexpr auto getTypeKindValues() noexcept +{ + return included::getTypeKindValues(); +} + +using DirectiveLocation = included::DirectiveLocation; + +constexpr auto getDirectiveLocationNames() noexcept +{ + return included::getDirectiveLocationNames(); +} + +constexpr auto getDirectiveLocationValues() noexcept +{ + return included::getDirectiveLocationValues(); +} + +void AddSchemaDetails(const std::shared_ptr& typeSchema, + const std::shared_ptr& schema) +{ + included::AddSchemaDetails(typeSchema, schema); +} + +void AddTypeDetails(const std::shared_ptr& typeType, + const std::shared_ptr& schema) +{ + included::AddTypeDetails(typeType, schema); +} + +void AddFieldDetails(const std::shared_ptr& typeField, + const std::shared_ptr& schema) +{ + included::AddFieldDetails(typeField, schema); +} + +void AddInputValueDetails(const std::shared_ptr& typeInputValue, + const std::shared_ptr& schema) +{ + included::AddInputValueDetails(typeInputValue, schema); +} + +void AddEnumValueDetails(const std::shared_ptr& typeEnumValue, + const std::shared_ptr& schema) +{ + included::AddEnumValueDetails(typeEnumValue, schema); +} + +void AddDirectiveDetails(const std::shared_ptr& typeDirective, + const std::shared_ptr& schema) +{ + included::AddDirectiveDetails(typeDirective, schema); +} + +void AddTypesToSchema(const std::shared_ptr& schema) +{ + included::AddTypesToSchema(schema); +} + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection diff --git a/include/graphqlservice/introspection/SchemaObject.ixx b/include/graphqlservice/introspection/SchemaObject.ixx new file mode 100644 index 00000000..b96287b2 --- /dev/null +++ b/include/graphqlservice/introspection/SchemaObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SchemaObject.h" + +export module GraphQL.Introspection.SchemaObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using Schema = included::Schema; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/TypeObject.ixx b/include/graphqlservice/introspection/TypeObject.ixx new file mode 100644 index 00000000..1c16e7a1 --- /dev/null +++ b/include/graphqlservice/introspection/TypeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TypeObject.h" + +export module GraphQL.Introspection.TypeObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using Type = included::Type; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8de9ff6e..850b29b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -73,15 +73,15 @@ endfunction() file(REAL_PATH ../include/ INCLUDE_ROOT) -# graphql_internal_module -add_library(graphql_internal_module STATIC) -add_library(cppgraphqlgen::graphql_internal_module ALIAS graphql_internal_module) -target_compile_features(graphql_internal_module PUBLIC cxx_std_20) -target_link_libraries(graphql_internal_module PUBLIC taocpp::pegtl) -target_include_directories(graphql_internal_module PUBLIC +# graphql_internal_modules +add_library(graphql_internal_modules STATIC) +add_library(cppgraphqlgen::graphql_internal_modules ALIAS graphql_internal_modules) +target_compile_features(graphql_internal_modules PUBLIC cxx_std_20) +target_link_libraries(graphql_internal_modules PUBLIC taocpp::pegtl) +target_include_directories(graphql_internal_modules PUBLIC $ $) -target_sources(graphql_internal_module +target_sources(graphql_internal_modules PUBLIC FILE_SET HEADERS BASE_DIRS ${INCLUDE_ROOT} @@ -107,6 +107,28 @@ target_sources(graphql_internal_module ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.ixx ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx) +# graphql_introspection_modules +add_library(graphql_introspection_modules STATIC) +add_library(cppgraphqlgen::graphql_introspection_modules ALIAS graphql_introspection_modules) +target_compile_features(graphql_introspection_modules PUBLIC cxx_std_20) +target_link_libraries(graphql_introspection_modules PUBLIC taocpp::pegtl) +target_include_directories(graphql_introspection_modules PUBLIC + $ + $) +file(GLOB INTROSPECTION_HEADERS ${INCLUDE_ROOT}/graphqlservice/introspection/*.h) +file(GLOB INTROSPECTION_MODULES ${INCLUDE_ROOT}/graphqlservice/introspection/*.ixx) +target_sources(graphql_introspection_modules + PUBLIC FILE_SET HEADERS + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INTROSPECTION_HEADERS} + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INTROSPECTION_MODULES}) + function(check_coroutine_impl OPTIONAL_FLAGS OUT_RESULT) set(TEST_FILE "test_coroutine.cpp") file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/${TEST_FILE} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) @@ -127,7 +149,7 @@ function(check_coroutine_impl OPTIONAL_FLAGS OUT_RESULT) if(TEST_RESULT) # Looks like the optional flag was required, go ahead and add it to the compile options. - target_compile_options(graphql_internal_module INTERFACE ${OPTIONAL_FLAG}) + target_compile_options(graphql_internal_modules INTERFACE ${OPTIONAL_FLAG}) break() endif() endforeach(OPTIONAL_FLAG) @@ -174,7 +196,7 @@ target_compile_features(graphqlresponse PUBLIC cxx_std_20) target_include_directories(graphqlresponse PUBLIC $ $) -target_link_libraries(graphqlresponse PUBLIC graphql_internal_module) +target_link_libraries(graphqlresponse PUBLIC graphql_internal_modules) if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqlresponse) @@ -358,7 +380,8 @@ add_library(graphqlservice add_library(cppgraphqlgen::graphqlservice ALIAS graphqlservice) target_compile_features(graphqlservice PUBLIC cxx_std_20) target_link_libraries(graphqlservice PUBLIC - graphql_internal_module + graphql_internal_modules + graphql_introspection_modules graphqlpeg graphqlresponse Threads::Threads) @@ -433,7 +456,8 @@ if(GRAPHQL_USE_RAPIDJSON) endif() install(TARGETS - graphql_internal_module + graphql_internal_modules + graphql_introspection_modules graphqlclient graphqlpeg graphqlresponse diff --git a/src/introspection/CMakeLists.txt b/src/introspection/CMakeLists.txt index 329b95a7..841bbb9f 100644 --- a/src/introspection/CMakeLists.txt +++ b/src/introspection/CMakeLists.txt @@ -20,8 +20,3 @@ if(GRAPHQL_UPDATE_SAMPLES) add_custom_target(copy_introspection_schema_headers ALL DEPENDS copied_introspection_schema_headers) endif() - -file(GLOB PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../../include/graphqlservice/introspection/*.h) -install(FILES ${PUBLIC_HEADERS} - CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} - DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}/graphqlservice/introspection) From c928aa4b26d1461cc0ffecc451f365b3c0f3354b Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 01:36:13 -0700 Subject: [PATCH 032/123] feat(modules): generate public interface modules in schemagen --- cmake/cppgraphqlgen-functions.cmake | 14 + cmake/cppgraphqlgen-update-schema-files.cmake | 9 +- include/SchemaGenerator.h | 6 + .../introspection/IntrospectionSchema.ixx | 20 +- samples/learn/schema/CharacterObject.ixx | 24 ++ samples/learn/schema/DroidObject.ixx | 24 ++ samples/learn/schema/HumanObject.ixx | 24 ++ samples/learn/schema/MutationObject.ixx | 24 ++ samples/learn/schema/QueryObject.ixx | 24 ++ samples/learn/schema/ReviewObject.ixx | 24 ++ samples/learn/schema/StarWarsSchema.ixx | 73 +++++ samples/proxy/schema/ProxySchema.ixx | 34 +++ samples/proxy/schema/QueryObject.ixx | 24 ++ .../AppointmentConnectionObject.ixx | 24 ++ .../nointrospection/AppointmentEdgeObject.ixx | 24 ++ .../nointrospection/AppointmentObject.ixx | 24 ++ .../CompleteTaskPayloadObject.ixx | 24 ++ .../today/nointrospection/ExpensiveObject.ixx | 24 ++ .../FolderConnectionObject.ixx | 24 ++ .../nointrospection/FolderEdgeObject.ixx | 24 ++ .../today/nointrospection/FolderObject.ixx | 24 ++ .../today/nointrospection/MutationObject.ixx | 24 ++ .../nointrospection/NestedTypeObject.ixx | 24 ++ samples/today/nointrospection/NodeObject.ixx | 24 ++ .../today/nointrospection/PageInfoObject.ixx | 24 ++ samples/today/nointrospection/QueryObject.ixx | 24 ++ .../nointrospection/SubscriptionObject.ixx | 24 ++ .../nointrospection/TaskConnectionObject.ixx | 24 ++ .../today/nointrospection/TaskEdgeObject.ixx | 24 ++ samples/today/nointrospection/TaskObject.ixx | 24 ++ samples/today/nointrospection/TodaySchema.ixx | 141 ++++++++++ .../today/nointrospection/UnionTypeObject.ixx | 24 ++ .../schema/AppointmentConnectionObject.ixx | 24 ++ .../today/schema/AppointmentEdgeObject.ixx | 24 ++ samples/today/schema/AppointmentObject.ixx | 24 ++ .../schema/CompleteTaskPayloadObject.ixx | 24 ++ samples/today/schema/ExpensiveObject.ixx | 24 ++ .../today/schema/FolderConnectionObject.ixx | 24 ++ samples/today/schema/FolderEdgeObject.ixx | 24 ++ samples/today/schema/FolderObject.ixx | 24 ++ samples/today/schema/MutationObject.ixx | 24 ++ samples/today/schema/NestedTypeObject.ixx | 24 ++ samples/today/schema/NodeObject.ixx | 24 ++ samples/today/schema/PageInfoObject.ixx | 24 ++ samples/today/schema/QueryObject.ixx | 24 ++ samples/today/schema/SubscriptionObject.ixx | 24 ++ samples/today/schema/TaskConnectionObject.ixx | 24 ++ samples/today/schema/TaskEdgeObject.ixx | 24 ++ samples/today/schema/TaskObject.ixx | 24 ++ samples/today/schema/TodaySchema.ixx | 141 ++++++++++ samples/today/schema/UnionTypeObject.ixx | 24 ++ samples/validation/schema/AlienObject.ixx | 24 ++ samples/validation/schema/ArgumentsObject.ixx | 24 ++ samples/validation/schema/CatObject.ixx | 24 ++ samples/validation/schema/CatOrDogObject.ixx | 24 ++ samples/validation/schema/DogObject.ixx | 24 ++ .../validation/schema/DogOrHumanObject.ixx | 24 ++ samples/validation/schema/HumanObject.ixx | 24 ++ .../validation/schema/HumanOrAlienObject.ixx | 24 ++ samples/validation/schema/MessageObject.ixx | 24 ++ .../schema/MutateDogResultObject.ixx | 24 ++ samples/validation/schema/MutationObject.ixx | 24 ++ samples/validation/schema/NodeObject.ixx | 24 ++ samples/validation/schema/PetObject.ixx | 24 ++ samples/validation/schema/QueryObject.ixx | 24 ++ samples/validation/schema/ResourceObject.ixx | 24 ++ samples/validation/schema/SentientObject.ixx | 24 ++ .../validation/schema/SubscriptionObject.ixx | 24 ++ .../validation/schema/ValidationSchema.ixx | 140 ++++++++++ src/SchemaGenerator.cpp | 263 +++++++++++++++++- src/introspection/CMakeLists.txt | 5 +- src/introspection/DirectiveObject.ixx | 24 ++ src/introspection/EnumValueObject.ixx | 24 ++ src/introspection/FieldObject.ixx | 24 ++ src/introspection/InputValueObject.ixx | 24 ++ src/introspection/IntrospectionSchema.ixx | 81 ++++++ src/introspection/SchemaObject.ixx | 24 ++ src/introspection/TypeObject.ixx | 24 ++ 78 files changed, 2489 insertions(+), 22 deletions(-) create mode 100644 samples/learn/schema/CharacterObject.ixx create mode 100644 samples/learn/schema/DroidObject.ixx create mode 100644 samples/learn/schema/HumanObject.ixx create mode 100644 samples/learn/schema/MutationObject.ixx create mode 100644 samples/learn/schema/QueryObject.ixx create mode 100644 samples/learn/schema/ReviewObject.ixx create mode 100644 samples/learn/schema/StarWarsSchema.ixx create mode 100644 samples/proxy/schema/ProxySchema.ixx create mode 100644 samples/proxy/schema/QueryObject.ixx create mode 100644 samples/today/nointrospection/AppointmentConnectionObject.ixx create mode 100644 samples/today/nointrospection/AppointmentEdgeObject.ixx create mode 100644 samples/today/nointrospection/AppointmentObject.ixx create mode 100644 samples/today/nointrospection/CompleteTaskPayloadObject.ixx create mode 100644 samples/today/nointrospection/ExpensiveObject.ixx create mode 100644 samples/today/nointrospection/FolderConnectionObject.ixx create mode 100644 samples/today/nointrospection/FolderEdgeObject.ixx create mode 100644 samples/today/nointrospection/FolderObject.ixx create mode 100644 samples/today/nointrospection/MutationObject.ixx create mode 100644 samples/today/nointrospection/NestedTypeObject.ixx create mode 100644 samples/today/nointrospection/NodeObject.ixx create mode 100644 samples/today/nointrospection/PageInfoObject.ixx create mode 100644 samples/today/nointrospection/QueryObject.ixx create mode 100644 samples/today/nointrospection/SubscriptionObject.ixx create mode 100644 samples/today/nointrospection/TaskConnectionObject.ixx create mode 100644 samples/today/nointrospection/TaskEdgeObject.ixx create mode 100644 samples/today/nointrospection/TaskObject.ixx create mode 100644 samples/today/nointrospection/TodaySchema.ixx create mode 100644 samples/today/nointrospection/UnionTypeObject.ixx create mode 100644 samples/today/schema/AppointmentConnectionObject.ixx create mode 100644 samples/today/schema/AppointmentEdgeObject.ixx create mode 100644 samples/today/schema/AppointmentObject.ixx create mode 100644 samples/today/schema/CompleteTaskPayloadObject.ixx create mode 100644 samples/today/schema/ExpensiveObject.ixx create mode 100644 samples/today/schema/FolderConnectionObject.ixx create mode 100644 samples/today/schema/FolderEdgeObject.ixx create mode 100644 samples/today/schema/FolderObject.ixx create mode 100644 samples/today/schema/MutationObject.ixx create mode 100644 samples/today/schema/NestedTypeObject.ixx create mode 100644 samples/today/schema/NodeObject.ixx create mode 100644 samples/today/schema/PageInfoObject.ixx create mode 100644 samples/today/schema/QueryObject.ixx create mode 100644 samples/today/schema/SubscriptionObject.ixx create mode 100644 samples/today/schema/TaskConnectionObject.ixx create mode 100644 samples/today/schema/TaskEdgeObject.ixx create mode 100644 samples/today/schema/TaskObject.ixx create mode 100644 samples/today/schema/TodaySchema.ixx create mode 100644 samples/today/schema/UnionTypeObject.ixx create mode 100644 samples/validation/schema/AlienObject.ixx create mode 100644 samples/validation/schema/ArgumentsObject.ixx create mode 100644 samples/validation/schema/CatObject.ixx create mode 100644 samples/validation/schema/CatOrDogObject.ixx create mode 100644 samples/validation/schema/DogObject.ixx create mode 100644 samples/validation/schema/DogOrHumanObject.ixx create mode 100644 samples/validation/schema/HumanObject.ixx create mode 100644 samples/validation/schema/HumanOrAlienObject.ixx create mode 100644 samples/validation/schema/MessageObject.ixx create mode 100644 samples/validation/schema/MutateDogResultObject.ixx create mode 100644 samples/validation/schema/MutationObject.ixx create mode 100644 samples/validation/schema/NodeObject.ixx create mode 100644 samples/validation/schema/PetObject.ixx create mode 100644 samples/validation/schema/QueryObject.ixx create mode 100644 samples/validation/schema/ResourceObject.ixx create mode 100644 samples/validation/schema/SentientObject.ixx create mode 100644 samples/validation/schema/SubscriptionObject.ixx create mode 100644 samples/validation/schema/ValidationSchema.ixx create mode 100644 src/introspection/DirectiveObject.ixx create mode 100644 src/introspection/EnumValueObject.ixx create mode 100644 src/introspection/FieldObject.ixx create mode 100644 src/introspection/InputValueObject.ixx create mode 100644 src/introspection/IntrospectionSchema.ixx create mode 100644 src/introspection/SchemaObject.ixx create mode 100644 src/introspection/TypeObject.ixx diff --git a/cmake/cppgraphqlgen-functions.cmake b/cmake/cppgraphqlgen-functions.cmake index 1ad5c95d..e37a02e0 100644 --- a/cmake/cppgraphqlgen-functions.cmake +++ b/cmake/cppgraphqlgen-functions.cmake @@ -44,10 +44,24 @@ function(add_graphql_schema_target SCHEMA_TARGET) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_TARGET}_schema_files) file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_TARGET}_schema_files SCHEMA_FILES) + file(GLOB SCHEMA_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) + file(GLOB SCHEMA_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) add_library(${SCHEMA_TARGET}_schema STATIC ${SCHEMA_FILES}) add_dependencies(${SCHEMA_TARGET}_schema ${SCHEMA_TARGET}_update_schema) + target_compile_features(${SCHEMA_TARGET}_schema PUBLIC cxx_std_20) target_include_directories(${SCHEMA_TARGET}_schema PUBLIC $) target_link_libraries(${SCHEMA_TARGET}_schema PUBLIC cppgraphqlgen::graphqlservice) + target_sources(${SCHEMA_TARGET}_schema + PUBLIC FILE_SET HEADERS + BASE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${SCHEMA_HEADERS} + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${SCHEMA_MODULES}) endif() endfunction() diff --git a/cmake/cppgraphqlgen-update-schema-files.cmake b/cmake/cppgraphqlgen-update-schema-files.cmake index 00d6fe06..8955f6fd 100644 --- a/cmake/cppgraphqlgen-update-schema-files.cmake +++ b/cmake/cppgraphqlgen-update-schema-files.cmake @@ -10,7 +10,7 @@ get_filename_component(SCHEMA_GRAPHQL "${SCHEMA_SOURCE_DIR}/${SCHEMA_GRAPHQL}" A file(MAKE_DIRECTORY ${SCHEMA_BINARY_DIR}) # Cleanup all of the stale files in the binary directory -file(GLOB PREVIOUS_FILES ${SCHEMA_BINARY_DIR}/*.h ${SCHEMA_BINARY_DIR}/*.cpp +file(GLOB PREVIOUS_FILES ${SCHEMA_BINARY_DIR}/*.h ${SCHEMA_BINARY_DIR}/*.ixx ${SCHEMA_BINARY_DIR}/*.cpp ${SCHEMA_BINARY_DIR}/${SCHEMA_TARGET}_schema_files) foreach(PREVIOUS_FILE ${PREVIOUS_FILES}) file(REMOVE ${PREVIOUS_FILE}) @@ -29,7 +29,7 @@ execute_process( # Get the up-to-date list of files in the binary directory set(FILE_NAMES "") -file(GLOB NEW_FILES ${SCHEMA_BINARY_DIR}/*.h ${SCHEMA_BINARY_DIR}/*.cpp) +file(GLOB NEW_FILES ${SCHEMA_BINARY_DIR}/*.h ${SCHEMA_BINARY_DIR}/*.ixx ${SCHEMA_BINARY_DIR}/*.cpp) foreach(NEW_FILE ${NEW_FILES}) get_filename_component(NEW_FILE ${NEW_FILE} NAME) list(APPEND FILE_NAMES "${NEW_FILE}") @@ -44,13 +44,14 @@ endif() cmake_policy(SET CMP0057 NEW) # Remove stale files in the source directory -file(GLOB OLD_FILES ${SCHEMA_SOURCE_DIR}/*.h ${SCHEMA_SOURCE_DIR}/*.cpp) +file(GLOB OLD_FILES ${SCHEMA_SOURCE_DIR}/*.h ${SCHEMA_SOURCE_DIR}/*.ixx ${SCHEMA_SOURCE_DIR}/*.cpp) foreach(OLD_FILE ${OLD_FILES}) get_filename_component(OLD_FILE ${OLD_FILE} NAME) if(NOT OLD_FILE IN_LIST FILE_NAMES) - if(OLD_FILE MATCHES "Object\\.h$" OR OLD_FILE MATCHES "Object\\.cpp$") + if(OLD_FILE MATCHES "Object\\.h$" OR OLD_FILE MATCHES "Object\\.ixx$" OR OLD_FILE MATCHES "Object\\.cpp$") file(REMOVE "${SCHEMA_SOURCE_DIR}/${OLD_FILE}") elseif(NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.h" AND + NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.ixx" AND NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.cpp") message(WARNING "Unexpected file in ${SCHEMA_TARGET} GraphQL schema sources: ${OLD_FILE}") endif() diff --git a/include/SchemaGenerator.h b/include/SchemaGenerator.h index 20b12a64..225d2b1d 100644 --- a/include/SchemaGenerator.h +++ b/include/SchemaGenerator.h @@ -39,10 +39,14 @@ class [[nodiscard("unnecessary construction")]] Generator [[nodiscard("unnecessary memory copy")]] std::string getHeaderDir() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSourceDir() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getHeaderPath() const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getModulePath() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSourcePath() const noexcept; [[nodiscard("unnecessary call")]] bool outputHeader() const noexcept; + [[nodiscard("unnecessary call")]] bool outputModule() const noexcept; void outputInterfaceDeclaration(std::ostream& headerFile, std::string_view cppType) const; + void outputObjectModule( + std::ostream& moduleFile, std::string_view objectNamespace, std::string_view cppType) const; void outputObjectImplements(std::ostream& headerFile, const ObjectType& objectType) const; void outputObjectStubs(std::ostream& headerFile, const ObjectType& objectType) const; void outputObjectDeclaration( @@ -88,8 +92,10 @@ class [[nodiscard("unnecessary construction")]] Generator SchemaLoader _loader; const GeneratorOptions _options; const std::string _headerDir; + const std::string _moduleDir; const std::string _sourceDir; const std::string _headerPath; + const std::string _modulePath; const std::string _sourcePath; }; diff --git a/include/graphqlservice/introspection/IntrospectionSchema.ixx b/include/graphqlservice/introspection/IntrospectionSchema.ixx index c6f6c791..859747cb 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.ixx +++ b/include/graphqlservice/introspection/IntrospectionSchema.ixx @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// WARNING! Do not edit this file manually, your changes will be overwritten. + module; #include "IntrospectionSchema.h" @@ -37,38 +39,32 @@ constexpr auto getDirectiveLocationValues() noexcept return included::getDirectiveLocationValues(); } -void AddSchemaDetails(const std::shared_ptr& typeSchema, - const std::shared_ptr& schema) +void AddSchemaDetails(const std::shared_ptr& typeSchema, const std::shared_ptr& schema) { included::AddSchemaDetails(typeSchema, schema); } -void AddTypeDetails(const std::shared_ptr& typeType, - const std::shared_ptr& schema) +void AddTypeDetails(const std::shared_ptr& typeType, const std::shared_ptr& schema) { included::AddTypeDetails(typeType, schema); } -void AddFieldDetails(const std::shared_ptr& typeField, - const std::shared_ptr& schema) +void AddFieldDetails(const std::shared_ptr& typeField, const std::shared_ptr& schema) { included::AddFieldDetails(typeField, schema); } -void AddInputValueDetails(const std::shared_ptr& typeInputValue, - const std::shared_ptr& schema) +void AddInputValueDetails(const std::shared_ptr& typeInputValue, const std::shared_ptr& schema) { included::AddInputValueDetails(typeInputValue, schema); } -void AddEnumValueDetails(const std::shared_ptr& typeEnumValue, - const std::shared_ptr& schema) +void AddEnumValueDetails(const std::shared_ptr& typeEnumValue, const std::shared_ptr& schema) { included::AddEnumValueDetails(typeEnumValue, schema); } -void AddDirectiveDetails(const std::shared_ptr& typeDirective, - const std::shared_ptr& schema) +void AddDirectiveDetails(const std::shared_ptr& typeDirective, const std::shared_ptr& schema) { included::AddDirectiveDetails(typeDirective, schema); } diff --git a/samples/learn/schema/CharacterObject.ixx b/samples/learn/schema/CharacterObject.ixx new file mode 100644 index 00000000..d1803df5 --- /dev/null +++ b/samples/learn/schema/CharacterObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "CharacterObject.h" + +export module GraphQL.StarWars.CharacterObject; + +namespace included = graphql::learn::object; + +export namespace graphql::learn::object { + +namespace exported { + +using Character = included::Character; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/DroidObject.ixx b/samples/learn/schema/DroidObject.ixx new file mode 100644 index 00000000..617a0b0d --- /dev/null +++ b/samples/learn/schema/DroidObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "DroidObject.h" + +export module GraphQL.StarWars.DroidObject; + +namespace included = graphql::learn::object; + +export namespace graphql::learn::object { + +namespace exported { + +using Droid = included::Droid; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/HumanObject.ixx b/samples/learn/schema/HumanObject.ixx new file mode 100644 index 00000000..5460899c --- /dev/null +++ b/samples/learn/schema/HumanObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "HumanObject.h" + +export module GraphQL.StarWars.HumanObject; + +namespace included = graphql::learn::object; + +export namespace graphql::learn::object { + +namespace exported { + +using Human = included::Human; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/MutationObject.ixx b/samples/learn/schema/MutationObject.ixx new file mode 100644 index 00000000..d31584be --- /dev/null +++ b/samples/learn/schema/MutationObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutationObject.h" + +export module GraphQL.StarWars.MutationObject; + +namespace included = graphql::learn::object; + +export namespace graphql::learn::object { + +namespace exported { + +using Mutation = included::Mutation; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/QueryObject.ixx b/samples/learn/schema/QueryObject.ixx new file mode 100644 index 00000000..55b289db --- /dev/null +++ b/samples/learn/schema/QueryObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryObject.h" + +export module GraphQL.StarWars.QueryObject; + +namespace included = graphql::learn::object; + +export namespace graphql::learn::object { + +namespace exported { + +using Query = included::Query; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/ReviewObject.ixx b/samples/learn/schema/ReviewObject.ixx new file mode 100644 index 00000000..a31c333d --- /dev/null +++ b/samples/learn/schema/ReviewObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ReviewObject.h" + +export module GraphQL.StarWars.ReviewObject; + +namespace included = graphql::learn::object; + +export namespace graphql::learn::object { + +namespace exported { + +using Review = included::Review; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/StarWarsSchema.ixx b/samples/learn/schema/StarWarsSchema.ixx new file mode 100644 index 00000000..be2a0853 --- /dev/null +++ b/samples/learn/schema/StarWarsSchema.ixx @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "StarWarsSchema.h" + +export module GraphQL.StarWars.StarWarsSchema; + +namespace included = graphql::learn; + +export namespace graphql::learn { + +namespace exported { + +using Episode = included::Episode; + +constexpr auto getEpisodeNames() noexcept +{ + return included::getEpisodeNames(); +} + +constexpr auto getEpisodeValues() noexcept +{ + return included::getEpisodeValues(); +} + +using ReviewInput= included::ReviewInput; + +using Operations = included::Operations; + +void AddCharacterDetails(const std::shared_ptr& typeCharacter, const std::shared_ptr& schema) +{ + included::AddCharacterDetails(typeCharacter, schema); +} + +void AddHumanDetails(const std::shared_ptr& typeHuman, const std::shared_ptr& schema) +{ + included::AddHumanDetails(typeHuman, schema); +} + +void AddDroidDetails(const std::shared_ptr& typeDroid, const std::shared_ptr& schema) +{ + included::AddDroidDetails(typeDroid, schema); +} + +void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) +{ + included::AddQueryDetails(typeQuery, schema); +} + +void AddReviewDetails(const std::shared_ptr& typeReview, const std::shared_ptr& schema) +{ + included::AddReviewDetails(typeReview, schema); +} + +void AddMutationDetails(const std::shared_ptr& typeMutation, const std::shared_ptr& schema) +{ + included::AddMutationDetails(typeMutation, schema); +} + +std::shared_ptr GetSchema() +{ + return included::GetSchema(); +} + +} // namespace exported + +using namespace exported; + +} // namespace graphql::learn diff --git a/samples/proxy/schema/ProxySchema.ixx b/samples/proxy/schema/ProxySchema.ixx new file mode 100644 index 00000000..6a6166bd --- /dev/null +++ b/samples/proxy/schema/ProxySchema.ixx @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ProxySchema.h" + +export module GraphQL.Proxy.ProxySchema; + +namespace included = graphql::proxy; + +export namespace graphql::proxy { + +namespace exported { + +using Operations = included::Operations; + +void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) +{ + included::AddQueryDetails(typeQuery, schema); +} + +std::shared_ptr GetSchema() +{ + return included::GetSchema(); +} + +} // namespace exported + +using namespace exported; + +} // namespace graphql::proxy diff --git a/samples/proxy/schema/QueryObject.ixx b/samples/proxy/schema/QueryObject.ixx new file mode 100644 index 00000000..55a7a1ca --- /dev/null +++ b/samples/proxy/schema/QueryObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryObject.h" + +export module GraphQL.Proxy.QueryObject; + +namespace included = graphql::proxy::object; + +export namespace graphql::proxy::object { + +namespace exported { + +using Query = included::Query; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::proxy::object diff --git a/samples/today/nointrospection/AppointmentConnectionObject.ixx b/samples/today/nointrospection/AppointmentConnectionObject.ixx new file mode 100644 index 00000000..43f105e3 --- /dev/null +++ b/samples/today/nointrospection/AppointmentConnectionObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentConnectionObject.h" + +export module GraphQL.Today.AppointmentConnectionObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using AppointmentConnection = included::AppointmentConnection; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/AppointmentEdgeObject.ixx b/samples/today/nointrospection/AppointmentEdgeObject.ixx new file mode 100644 index 00000000..f90e04aa --- /dev/null +++ b/samples/today/nointrospection/AppointmentEdgeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentEdgeObject.h" + +export module GraphQL.Today.AppointmentEdgeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using AppointmentEdge = included::AppointmentEdge; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/AppointmentObject.ixx b/samples/today/nointrospection/AppointmentObject.ixx new file mode 100644 index 00000000..5d166480 --- /dev/null +++ b/samples/today/nointrospection/AppointmentObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentObject.h" + +export module GraphQL.Today.AppointmentObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Appointment = included::Appointment; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/CompleteTaskPayloadObject.ixx b/samples/today/nointrospection/CompleteTaskPayloadObject.ixx new file mode 100644 index 00000000..57fadd1a --- /dev/null +++ b/samples/today/nointrospection/CompleteTaskPayloadObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "CompleteTaskPayloadObject.h" + +export module GraphQL.Today.CompleteTaskPayloadObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using CompleteTaskPayload = included::CompleteTaskPayload; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/ExpensiveObject.ixx b/samples/today/nointrospection/ExpensiveObject.ixx new file mode 100644 index 00000000..d0d0f9cf --- /dev/null +++ b/samples/today/nointrospection/ExpensiveObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ExpensiveObject.h" + +export module GraphQL.Today.ExpensiveObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Expensive = included::Expensive; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/FolderConnectionObject.ixx b/samples/today/nointrospection/FolderConnectionObject.ixx new file mode 100644 index 00000000..82c8fad0 --- /dev/null +++ b/samples/today/nointrospection/FolderConnectionObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderConnectionObject.h" + +export module GraphQL.Today.FolderConnectionObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using FolderConnection = included::FolderConnection; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/FolderEdgeObject.ixx b/samples/today/nointrospection/FolderEdgeObject.ixx new file mode 100644 index 00000000..28317740 --- /dev/null +++ b/samples/today/nointrospection/FolderEdgeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderEdgeObject.h" + +export module GraphQL.Today.FolderEdgeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using FolderEdge = included::FolderEdge; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/FolderObject.ixx b/samples/today/nointrospection/FolderObject.ixx new file mode 100644 index 00000000..c8b36149 --- /dev/null +++ b/samples/today/nointrospection/FolderObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderObject.h" + +export module GraphQL.Today.FolderObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Folder = included::Folder; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/MutationObject.ixx b/samples/today/nointrospection/MutationObject.ixx new file mode 100644 index 00000000..5a2fd5ed --- /dev/null +++ b/samples/today/nointrospection/MutationObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutationObject.h" + +export module GraphQL.Today.MutationObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Mutation = included::Mutation; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/NestedTypeObject.ixx b/samples/today/nointrospection/NestedTypeObject.ixx new file mode 100644 index 00000000..095cdf82 --- /dev/null +++ b/samples/today/nointrospection/NestedTypeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NestedTypeObject.h" + +export module GraphQL.Today.NestedTypeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using NestedType = included::NestedType; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/NodeObject.ixx b/samples/today/nointrospection/NodeObject.ixx new file mode 100644 index 00000000..558df3ef --- /dev/null +++ b/samples/today/nointrospection/NodeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NodeObject.h" + +export module GraphQL.Today.NodeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Node = included::Node; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/PageInfoObject.ixx b/samples/today/nointrospection/PageInfoObject.ixx new file mode 100644 index 00000000..7ef13425 --- /dev/null +++ b/samples/today/nointrospection/PageInfoObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "PageInfoObject.h" + +export module GraphQL.Today.PageInfoObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using PageInfo = included::PageInfo; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/QueryObject.ixx b/samples/today/nointrospection/QueryObject.ixx new file mode 100644 index 00000000..8a2b3938 --- /dev/null +++ b/samples/today/nointrospection/QueryObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryObject.h" + +export module GraphQL.Today.QueryObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Query = included::Query; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/SubscriptionObject.ixx b/samples/today/nointrospection/SubscriptionObject.ixx new file mode 100644 index 00000000..3c359438 --- /dev/null +++ b/samples/today/nointrospection/SubscriptionObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SubscriptionObject.h" + +export module GraphQL.Today.SubscriptionObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Subscription = included::Subscription; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/TaskConnectionObject.ixx b/samples/today/nointrospection/TaskConnectionObject.ixx new file mode 100644 index 00000000..57c8c868 --- /dev/null +++ b/samples/today/nointrospection/TaskConnectionObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskConnectionObject.h" + +export module GraphQL.Today.TaskConnectionObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using TaskConnection = included::TaskConnection; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/TaskEdgeObject.ixx b/samples/today/nointrospection/TaskEdgeObject.ixx new file mode 100644 index 00000000..52d7a41f --- /dev/null +++ b/samples/today/nointrospection/TaskEdgeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskEdgeObject.h" + +export module GraphQL.Today.TaskEdgeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using TaskEdge = included::TaskEdge; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/TaskObject.ixx b/samples/today/nointrospection/TaskObject.ixx new file mode 100644 index 00000000..a6d15c00 --- /dev/null +++ b/samples/today/nointrospection/TaskObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskObject.h" + +export module GraphQL.Today.TaskObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Task = included::Task; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/TodaySchema.ixx b/samples/today/nointrospection/TodaySchema.ixx new file mode 100644 index 00000000..1cce90c6 --- /dev/null +++ b/samples/today/nointrospection/TodaySchema.ixx @@ -0,0 +1,141 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TodaySchema.h" + +export module GraphQL.Today.TodaySchema; + +namespace included = graphql::today; + +export namespace graphql::today { + +namespace exported { + +using TaskState = included::TaskState; + +constexpr auto getTaskStateNames() noexcept +{ + return included::getTaskStateNames(); +} + +constexpr auto getTaskStateValues() noexcept +{ + return included::getTaskStateValues(); +} + +using CompleteTaskInput= included::CompleteTaskInput; +using ThirdNestedInput= included::ThirdNestedInput; +using FourthNestedInput= included::FourthNestedInput; +using IncludeNullableSelfInput= included::IncludeNullableSelfInput; +using IncludeNonNullableListSelfInput= included::IncludeNonNullableListSelfInput; +using StringOperationFilterInput= included::StringOperationFilterInput; +using SecondNestedInput= included::SecondNestedInput; +using ForwardDeclaredInput= included::ForwardDeclaredInput; +using FirstNestedInput= included::FirstNestedInput; + +using Operations = included::Operations; + +void AddNodeDetails(const std::shared_ptr& typeNode, const std::shared_ptr& schema) +{ + included::AddNodeDetails(typeNode, schema); +} + +void AddUnionTypeDetails(const std::shared_ptr& typeUnionType, const std::shared_ptr& schema) +{ + included::AddUnionTypeDetails(typeUnionType, schema); +} + +void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) +{ + included::AddQueryDetails(typeQuery, schema); +} + +void AddPageInfoDetails(const std::shared_ptr& typePageInfo, const std::shared_ptr& schema) +{ + included::AddPageInfoDetails(typePageInfo, schema); +} + +void AddAppointmentEdgeDetails(const std::shared_ptr& typeAppointmentEdge, const std::shared_ptr& schema) +{ + included::AddAppointmentEdgeDetails(typeAppointmentEdge, schema); +} + +void AddAppointmentConnectionDetails(const std::shared_ptr& typeAppointmentConnection, const std::shared_ptr& schema) +{ + included::AddAppointmentConnectionDetails(typeAppointmentConnection, schema); +} + +void AddTaskEdgeDetails(const std::shared_ptr& typeTaskEdge, const std::shared_ptr& schema) +{ + included::AddTaskEdgeDetails(typeTaskEdge, schema); +} + +void AddTaskConnectionDetails(const std::shared_ptr& typeTaskConnection, const std::shared_ptr& schema) +{ + included::AddTaskConnectionDetails(typeTaskConnection, schema); +} + +void AddFolderEdgeDetails(const std::shared_ptr& typeFolderEdge, const std::shared_ptr& schema) +{ + included::AddFolderEdgeDetails(typeFolderEdge, schema); +} + +void AddFolderConnectionDetails(const std::shared_ptr& typeFolderConnection, const std::shared_ptr& schema) +{ + included::AddFolderConnectionDetails(typeFolderConnection, schema); +} + +void AddCompleteTaskPayloadDetails(const std::shared_ptr& typeCompleteTaskPayload, const std::shared_ptr& schema) +{ + included::AddCompleteTaskPayloadDetails(typeCompleteTaskPayload, schema); +} + +void AddMutationDetails(const std::shared_ptr& typeMutation, const std::shared_ptr& schema) +{ + included::AddMutationDetails(typeMutation, schema); +} + +void AddSubscriptionDetails(const std::shared_ptr& typeSubscription, const std::shared_ptr& schema) +{ + included::AddSubscriptionDetails(typeSubscription, schema); +} + +void AddAppointmentDetails(const std::shared_ptr& typeAppointment, const std::shared_ptr& schema) +{ + included::AddAppointmentDetails(typeAppointment, schema); +} + +void AddTaskDetails(const std::shared_ptr& typeTask, const std::shared_ptr& schema) +{ + included::AddTaskDetails(typeTask, schema); +} + +void AddFolderDetails(const std::shared_ptr& typeFolder, const std::shared_ptr& schema) +{ + included::AddFolderDetails(typeFolder, schema); +} + +void AddNestedTypeDetails(const std::shared_ptr& typeNestedType, const std::shared_ptr& schema) +{ + included::AddNestedTypeDetails(typeNestedType, schema); +} + +void AddExpensiveDetails(const std::shared_ptr& typeExpensive, const std::shared_ptr& schema) +{ + included::AddExpensiveDetails(typeExpensive, schema); +} + +std::shared_ptr GetSchema() +{ + return included::GetSchema(); +} + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today diff --git a/samples/today/nointrospection/UnionTypeObject.ixx b/samples/today/nointrospection/UnionTypeObject.ixx new file mode 100644 index 00000000..dfca5cc6 --- /dev/null +++ b/samples/today/nointrospection/UnionTypeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "UnionTypeObject.h" + +export module GraphQL.Today.UnionTypeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using UnionType = included::UnionType; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/AppointmentConnectionObject.ixx b/samples/today/schema/AppointmentConnectionObject.ixx new file mode 100644 index 00000000..43f105e3 --- /dev/null +++ b/samples/today/schema/AppointmentConnectionObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentConnectionObject.h" + +export module GraphQL.Today.AppointmentConnectionObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using AppointmentConnection = included::AppointmentConnection; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/AppointmentEdgeObject.ixx b/samples/today/schema/AppointmentEdgeObject.ixx new file mode 100644 index 00000000..f90e04aa --- /dev/null +++ b/samples/today/schema/AppointmentEdgeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentEdgeObject.h" + +export module GraphQL.Today.AppointmentEdgeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using AppointmentEdge = included::AppointmentEdge; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/AppointmentObject.ixx b/samples/today/schema/AppointmentObject.ixx new file mode 100644 index 00000000..5d166480 --- /dev/null +++ b/samples/today/schema/AppointmentObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentObject.h" + +export module GraphQL.Today.AppointmentObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Appointment = included::Appointment; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/CompleteTaskPayloadObject.ixx b/samples/today/schema/CompleteTaskPayloadObject.ixx new file mode 100644 index 00000000..57fadd1a --- /dev/null +++ b/samples/today/schema/CompleteTaskPayloadObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "CompleteTaskPayloadObject.h" + +export module GraphQL.Today.CompleteTaskPayloadObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using CompleteTaskPayload = included::CompleteTaskPayload; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/ExpensiveObject.ixx b/samples/today/schema/ExpensiveObject.ixx new file mode 100644 index 00000000..d0d0f9cf --- /dev/null +++ b/samples/today/schema/ExpensiveObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ExpensiveObject.h" + +export module GraphQL.Today.ExpensiveObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Expensive = included::Expensive; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/FolderConnectionObject.ixx b/samples/today/schema/FolderConnectionObject.ixx new file mode 100644 index 00000000..82c8fad0 --- /dev/null +++ b/samples/today/schema/FolderConnectionObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderConnectionObject.h" + +export module GraphQL.Today.FolderConnectionObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using FolderConnection = included::FolderConnection; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/FolderEdgeObject.ixx b/samples/today/schema/FolderEdgeObject.ixx new file mode 100644 index 00000000..28317740 --- /dev/null +++ b/samples/today/schema/FolderEdgeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderEdgeObject.h" + +export module GraphQL.Today.FolderEdgeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using FolderEdge = included::FolderEdge; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/FolderObject.ixx b/samples/today/schema/FolderObject.ixx new file mode 100644 index 00000000..c8b36149 --- /dev/null +++ b/samples/today/schema/FolderObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderObject.h" + +export module GraphQL.Today.FolderObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Folder = included::Folder; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/MutationObject.ixx b/samples/today/schema/MutationObject.ixx new file mode 100644 index 00000000..5a2fd5ed --- /dev/null +++ b/samples/today/schema/MutationObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutationObject.h" + +export module GraphQL.Today.MutationObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Mutation = included::Mutation; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/NestedTypeObject.ixx b/samples/today/schema/NestedTypeObject.ixx new file mode 100644 index 00000000..095cdf82 --- /dev/null +++ b/samples/today/schema/NestedTypeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NestedTypeObject.h" + +export module GraphQL.Today.NestedTypeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using NestedType = included::NestedType; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/NodeObject.ixx b/samples/today/schema/NodeObject.ixx new file mode 100644 index 00000000..558df3ef --- /dev/null +++ b/samples/today/schema/NodeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NodeObject.h" + +export module GraphQL.Today.NodeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Node = included::Node; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/PageInfoObject.ixx b/samples/today/schema/PageInfoObject.ixx new file mode 100644 index 00000000..7ef13425 --- /dev/null +++ b/samples/today/schema/PageInfoObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "PageInfoObject.h" + +export module GraphQL.Today.PageInfoObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using PageInfo = included::PageInfo; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/QueryObject.ixx b/samples/today/schema/QueryObject.ixx new file mode 100644 index 00000000..8a2b3938 --- /dev/null +++ b/samples/today/schema/QueryObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryObject.h" + +export module GraphQL.Today.QueryObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Query = included::Query; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/SubscriptionObject.ixx b/samples/today/schema/SubscriptionObject.ixx new file mode 100644 index 00000000..3c359438 --- /dev/null +++ b/samples/today/schema/SubscriptionObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SubscriptionObject.h" + +export module GraphQL.Today.SubscriptionObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Subscription = included::Subscription; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/TaskConnectionObject.ixx b/samples/today/schema/TaskConnectionObject.ixx new file mode 100644 index 00000000..57c8c868 --- /dev/null +++ b/samples/today/schema/TaskConnectionObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskConnectionObject.h" + +export module GraphQL.Today.TaskConnectionObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using TaskConnection = included::TaskConnection; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/TaskEdgeObject.ixx b/samples/today/schema/TaskEdgeObject.ixx new file mode 100644 index 00000000..52d7a41f --- /dev/null +++ b/samples/today/schema/TaskEdgeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskEdgeObject.h" + +export module GraphQL.Today.TaskEdgeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using TaskEdge = included::TaskEdge; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/TaskObject.ixx b/samples/today/schema/TaskObject.ixx new file mode 100644 index 00000000..a6d15c00 --- /dev/null +++ b/samples/today/schema/TaskObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskObject.h" + +export module GraphQL.Today.TaskObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using Task = included::Task; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/today/schema/TodaySchema.ixx b/samples/today/schema/TodaySchema.ixx new file mode 100644 index 00000000..1cce90c6 --- /dev/null +++ b/samples/today/schema/TodaySchema.ixx @@ -0,0 +1,141 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TodaySchema.h" + +export module GraphQL.Today.TodaySchema; + +namespace included = graphql::today; + +export namespace graphql::today { + +namespace exported { + +using TaskState = included::TaskState; + +constexpr auto getTaskStateNames() noexcept +{ + return included::getTaskStateNames(); +} + +constexpr auto getTaskStateValues() noexcept +{ + return included::getTaskStateValues(); +} + +using CompleteTaskInput= included::CompleteTaskInput; +using ThirdNestedInput= included::ThirdNestedInput; +using FourthNestedInput= included::FourthNestedInput; +using IncludeNullableSelfInput= included::IncludeNullableSelfInput; +using IncludeNonNullableListSelfInput= included::IncludeNonNullableListSelfInput; +using StringOperationFilterInput= included::StringOperationFilterInput; +using SecondNestedInput= included::SecondNestedInput; +using ForwardDeclaredInput= included::ForwardDeclaredInput; +using FirstNestedInput= included::FirstNestedInput; + +using Operations = included::Operations; + +void AddNodeDetails(const std::shared_ptr& typeNode, const std::shared_ptr& schema) +{ + included::AddNodeDetails(typeNode, schema); +} + +void AddUnionTypeDetails(const std::shared_ptr& typeUnionType, const std::shared_ptr& schema) +{ + included::AddUnionTypeDetails(typeUnionType, schema); +} + +void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) +{ + included::AddQueryDetails(typeQuery, schema); +} + +void AddPageInfoDetails(const std::shared_ptr& typePageInfo, const std::shared_ptr& schema) +{ + included::AddPageInfoDetails(typePageInfo, schema); +} + +void AddAppointmentEdgeDetails(const std::shared_ptr& typeAppointmentEdge, const std::shared_ptr& schema) +{ + included::AddAppointmentEdgeDetails(typeAppointmentEdge, schema); +} + +void AddAppointmentConnectionDetails(const std::shared_ptr& typeAppointmentConnection, const std::shared_ptr& schema) +{ + included::AddAppointmentConnectionDetails(typeAppointmentConnection, schema); +} + +void AddTaskEdgeDetails(const std::shared_ptr& typeTaskEdge, const std::shared_ptr& schema) +{ + included::AddTaskEdgeDetails(typeTaskEdge, schema); +} + +void AddTaskConnectionDetails(const std::shared_ptr& typeTaskConnection, const std::shared_ptr& schema) +{ + included::AddTaskConnectionDetails(typeTaskConnection, schema); +} + +void AddFolderEdgeDetails(const std::shared_ptr& typeFolderEdge, const std::shared_ptr& schema) +{ + included::AddFolderEdgeDetails(typeFolderEdge, schema); +} + +void AddFolderConnectionDetails(const std::shared_ptr& typeFolderConnection, const std::shared_ptr& schema) +{ + included::AddFolderConnectionDetails(typeFolderConnection, schema); +} + +void AddCompleteTaskPayloadDetails(const std::shared_ptr& typeCompleteTaskPayload, const std::shared_ptr& schema) +{ + included::AddCompleteTaskPayloadDetails(typeCompleteTaskPayload, schema); +} + +void AddMutationDetails(const std::shared_ptr& typeMutation, const std::shared_ptr& schema) +{ + included::AddMutationDetails(typeMutation, schema); +} + +void AddSubscriptionDetails(const std::shared_ptr& typeSubscription, const std::shared_ptr& schema) +{ + included::AddSubscriptionDetails(typeSubscription, schema); +} + +void AddAppointmentDetails(const std::shared_ptr& typeAppointment, const std::shared_ptr& schema) +{ + included::AddAppointmentDetails(typeAppointment, schema); +} + +void AddTaskDetails(const std::shared_ptr& typeTask, const std::shared_ptr& schema) +{ + included::AddTaskDetails(typeTask, schema); +} + +void AddFolderDetails(const std::shared_ptr& typeFolder, const std::shared_ptr& schema) +{ + included::AddFolderDetails(typeFolder, schema); +} + +void AddNestedTypeDetails(const std::shared_ptr& typeNestedType, const std::shared_ptr& schema) +{ + included::AddNestedTypeDetails(typeNestedType, schema); +} + +void AddExpensiveDetails(const std::shared_ptr& typeExpensive, const std::shared_ptr& schema) +{ + included::AddExpensiveDetails(typeExpensive, schema); +} + +std::shared_ptr GetSchema() +{ + return included::GetSchema(); +} + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today diff --git a/samples/today/schema/UnionTypeObject.ixx b/samples/today/schema/UnionTypeObject.ixx new file mode 100644 index 00000000..dfca5cc6 --- /dev/null +++ b/samples/today/schema/UnionTypeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "UnionTypeObject.h" + +export module GraphQL.Today.UnionTypeObject; + +namespace included = graphql::today::object; + +export namespace graphql::today::object { + +namespace exported { + +using UnionType = included::UnionType; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::today::object diff --git a/samples/validation/schema/AlienObject.ixx b/samples/validation/schema/AlienObject.ixx new file mode 100644 index 00000000..fbfb2fe4 --- /dev/null +++ b/samples/validation/schema/AlienObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AlienObject.h" + +export module GraphQL.Validation.AlienObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Alien = included::Alien; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/ArgumentsObject.ixx b/samples/validation/schema/ArgumentsObject.ixx new file mode 100644 index 00000000..b207ec50 --- /dev/null +++ b/samples/validation/schema/ArgumentsObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ArgumentsObject.h" + +export module GraphQL.Validation.ArgumentsObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Arguments = included::Arguments; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/CatObject.ixx b/samples/validation/schema/CatObject.ixx new file mode 100644 index 00000000..0c82760e --- /dev/null +++ b/samples/validation/schema/CatObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "CatObject.h" + +export module GraphQL.Validation.CatObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Cat = included::Cat; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/CatOrDogObject.ixx b/samples/validation/schema/CatOrDogObject.ixx new file mode 100644 index 00000000..f557c5fc --- /dev/null +++ b/samples/validation/schema/CatOrDogObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "CatOrDogObject.h" + +export module GraphQL.Validation.CatOrDogObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using CatOrDog = included::CatOrDog; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/DogObject.ixx b/samples/validation/schema/DogObject.ixx new file mode 100644 index 00000000..4385c5f3 --- /dev/null +++ b/samples/validation/schema/DogObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "DogObject.h" + +export module GraphQL.Validation.DogObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Dog = included::Dog; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/DogOrHumanObject.ixx b/samples/validation/schema/DogOrHumanObject.ixx new file mode 100644 index 00000000..5f9c0cad --- /dev/null +++ b/samples/validation/schema/DogOrHumanObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "DogOrHumanObject.h" + +export module GraphQL.Validation.DogOrHumanObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using DogOrHuman = included::DogOrHuman; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/HumanObject.ixx b/samples/validation/schema/HumanObject.ixx new file mode 100644 index 00000000..e3abd321 --- /dev/null +++ b/samples/validation/schema/HumanObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "HumanObject.h" + +export module GraphQL.Validation.HumanObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Human = included::Human; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/HumanOrAlienObject.ixx b/samples/validation/schema/HumanOrAlienObject.ixx new file mode 100644 index 00000000..5a2b5a42 --- /dev/null +++ b/samples/validation/schema/HumanOrAlienObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "HumanOrAlienObject.h" + +export module GraphQL.Validation.HumanOrAlienObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using HumanOrAlien = included::HumanOrAlien; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/MessageObject.ixx b/samples/validation/schema/MessageObject.ixx new file mode 100644 index 00000000..4857282f --- /dev/null +++ b/samples/validation/schema/MessageObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MessageObject.h" + +export module GraphQL.Validation.MessageObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Message = included::Message; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/MutateDogResultObject.ixx b/samples/validation/schema/MutateDogResultObject.ixx new file mode 100644 index 00000000..045dd755 --- /dev/null +++ b/samples/validation/schema/MutateDogResultObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutateDogResultObject.h" + +export module GraphQL.Validation.MutateDogResultObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using MutateDogResult = included::MutateDogResult; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/MutationObject.ixx b/samples/validation/schema/MutationObject.ixx new file mode 100644 index 00000000..f189ff07 --- /dev/null +++ b/samples/validation/schema/MutationObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutationObject.h" + +export module GraphQL.Validation.MutationObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Mutation = included::Mutation; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/NodeObject.ixx b/samples/validation/schema/NodeObject.ixx new file mode 100644 index 00000000..5651b3b4 --- /dev/null +++ b/samples/validation/schema/NodeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NodeObject.h" + +export module GraphQL.Validation.NodeObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Node = included::Node; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/PetObject.ixx b/samples/validation/schema/PetObject.ixx new file mode 100644 index 00000000..fd893248 --- /dev/null +++ b/samples/validation/schema/PetObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "PetObject.h" + +export module GraphQL.Validation.PetObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Pet = included::Pet; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/QueryObject.ixx b/samples/validation/schema/QueryObject.ixx new file mode 100644 index 00000000..a2de1cc3 --- /dev/null +++ b/samples/validation/schema/QueryObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryObject.h" + +export module GraphQL.Validation.QueryObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Query = included::Query; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/ResourceObject.ixx b/samples/validation/schema/ResourceObject.ixx new file mode 100644 index 00000000..4c171957 --- /dev/null +++ b/samples/validation/schema/ResourceObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ResourceObject.h" + +export module GraphQL.Validation.ResourceObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Resource = included::Resource; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/SentientObject.ixx b/samples/validation/schema/SentientObject.ixx new file mode 100644 index 00000000..e7b6d35b --- /dev/null +++ b/samples/validation/schema/SentientObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SentientObject.h" + +export module GraphQL.Validation.SentientObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Sentient = included::Sentient; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/SubscriptionObject.ixx b/samples/validation/schema/SubscriptionObject.ixx new file mode 100644 index 00000000..8a51c9c4 --- /dev/null +++ b/samples/validation/schema/SubscriptionObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SubscriptionObject.h" + +export module GraphQL.Validation.SubscriptionObject; + +namespace included = graphql::validation::object; + +export namespace graphql::validation::object { + +namespace exported { + +using Subscription = included::Subscription; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/ValidationSchema.ixx b/samples/validation/schema/ValidationSchema.ixx new file mode 100644 index 00000000..f7baef11 --- /dev/null +++ b/samples/validation/schema/ValidationSchema.ixx @@ -0,0 +1,140 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ValidationSchema.h" + +export module GraphQL.Validation.ValidationSchema; + +namespace included = graphql::validation; + +export namespace graphql::validation { + +namespace exported { + +using DogCommand = included::DogCommand; + +constexpr auto getDogCommandNames() noexcept +{ + return included::getDogCommandNames(); +} + +constexpr auto getDogCommandValues() noexcept +{ + return included::getDogCommandValues(); +} + +using CatCommand = included::CatCommand; + +constexpr auto getCatCommandNames() noexcept +{ + return included::getCatCommandNames(); +} + +constexpr auto getCatCommandValues() noexcept +{ + return included::getCatCommandValues(); +} + +using ComplexInput= included::ComplexInput; + +using Operations = included::Operations; + +void AddSentientDetails(const std::shared_ptr& typeSentient, const std::shared_ptr& schema) +{ + included::AddSentientDetails(typeSentient, schema); +} + +void AddPetDetails(const std::shared_ptr& typePet, const std::shared_ptr& schema) +{ + included::AddPetDetails(typePet, schema); +} + +void AddNodeDetails(const std::shared_ptr& typeNode, const std::shared_ptr& schema) +{ + included::AddNodeDetails(typeNode, schema); +} + +void AddResourceDetails(const std::shared_ptr& typeResource, const std::shared_ptr& schema) +{ + included::AddResourceDetails(typeResource, schema); +} + +void AddCatOrDogDetails(const std::shared_ptr& typeCatOrDog, const std::shared_ptr& schema) +{ + included::AddCatOrDogDetails(typeCatOrDog, schema); +} + +void AddDogOrHumanDetails(const std::shared_ptr& typeDogOrHuman, const std::shared_ptr& schema) +{ + included::AddDogOrHumanDetails(typeDogOrHuman, schema); +} + +void AddHumanOrAlienDetails(const std::shared_ptr& typeHumanOrAlien, const std::shared_ptr& schema) +{ + included::AddHumanOrAlienDetails(typeHumanOrAlien, schema); +} + +void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) +{ + included::AddQueryDetails(typeQuery, schema); +} + +void AddDogDetails(const std::shared_ptr& typeDog, const std::shared_ptr& schema) +{ + included::AddDogDetails(typeDog, schema); +} + +void AddAlienDetails(const std::shared_ptr& typeAlien, const std::shared_ptr& schema) +{ + included::AddAlienDetails(typeAlien, schema); +} + +void AddHumanDetails(const std::shared_ptr& typeHuman, const std::shared_ptr& schema) +{ + included::AddHumanDetails(typeHuman, schema); +} + +void AddCatDetails(const std::shared_ptr& typeCat, const std::shared_ptr& schema) +{ + included::AddCatDetails(typeCat, schema); +} + +void AddMutationDetails(const std::shared_ptr& typeMutation, const std::shared_ptr& schema) +{ + included::AddMutationDetails(typeMutation, schema); +} + +void AddMutateDogResultDetails(const std::shared_ptr& typeMutateDogResult, const std::shared_ptr& schema) +{ + included::AddMutateDogResultDetails(typeMutateDogResult, schema); +} + +void AddSubscriptionDetails(const std::shared_ptr& typeSubscription, const std::shared_ptr& schema) +{ + included::AddSubscriptionDetails(typeSubscription, schema); +} + +void AddMessageDetails(const std::shared_ptr& typeMessage, const std::shared_ptr& schema) +{ + included::AddMessageDetails(typeMessage, schema); +} + +void AddArgumentsDetails(const std::shared_ptr& typeArguments, const std::shared_ptr& schema) +{ + included::AddArgumentsDetails(typeArguments, schema); +} + +std::shared_ptr GetSchema() +{ + return included::GetSchema(); +} + +} // namespace exported + +using namespace exported; + +} // namespace graphql::validation diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index ad376c62..0e76b294 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -38,6 +38,7 @@ Generator::Generator(SchemaOptions&& schemaOptions, GeneratorOptions&& options) , _headerDir(getHeaderDir()) , _sourceDir(getSourceDir()) , _headerPath(getHeaderPath()) + , _modulePath(getModulePath()) , _sourcePath(getSourcePath()) { } @@ -74,6 +75,14 @@ std::string Generator::getHeaderPath() const noexcept return fullPath.string(); } +std::string Generator::getModulePath() const noexcept +{ + std::filesystem::path fullPath { _headerDir }; + + fullPath /= (std::string { _loader.getFilenamePrefix() } + "Schema.ixx"); + return fullPath.string(); +} + std::string Generator::getSourcePath() const noexcept { std::filesystem::path fullPath { _sourceDir }; @@ -91,6 +100,11 @@ std::vector Generator::Build() const noexcept builtFiles.push_back(_headerPath); } + if (outputModule() && _options.verbose) + { + builtFiles.push_back(_modulePath); + } + if (outputSource()) { builtFiles.push_back(_sourcePath); @@ -671,6 +685,181 @@ GRAPHQLSERVICE_EXPORT )cpp" << _loader.getSchemaNamespace() return true; } +bool Generator::outputModule() const noexcept +{ + std::ofstream moduleFile(_modulePath, std::ios_base::trunc); + std::ostringstream ossNamespace; + + ossNamespace << R"cpp(graphql::)cpp" << _loader.getSchemaNamespace(); + + const auto schemaNamespace = ossNamespace.str(); + + moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include ")cpp" << _loader.getFilenamePrefix() + << + R"cpp(Schema.h" + +export module GraphQL.)cpp" + << _loader.getFilenamePrefix() << R"cpp(.)cpp" << _loader.getFilenamePrefix() << + R"cpp(Schema; + +namespace included = )cpp" + << schemaNamespace << R"cpp(; + +export )cpp"; + + NamespaceScope graphqlNamespace { moduleFile, schemaNamespace }; + + moduleFile << std::endl; + + NamespaceScope exportedNamespace { moduleFile, "exported" }; + PendingBlankLine pendingSeparator { moduleFile }; + + if (!_loader.getEnumTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& enumType : _loader.getEnumTypes()) + { + moduleFile << R"cpp(using )cpp" << enumType.cppType << R"cpp( = included::)cpp" + << enumType.cppType << R"cpp(; + +constexpr auto get)cpp" << enumType.cppType + << R"cpp(Names() noexcept +{ + return included::get)cpp" + << enumType.cppType << R"cpp(Names(); +} + +constexpr auto get)cpp" << enumType.cppType + << R"cpp(Values() noexcept +{ + return included::get)cpp" + << enumType.cppType << R"cpp(Values(); +} + +)cpp"; + } + } + + if (!_loader.getInputTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& inputType : _loader.getInputTypes()) + { + moduleFile << R"cpp(using )cpp" << inputType.cppType << R"cpp(= included::)cpp" + << inputType.cppType << R"cpp(; +)cpp"; + } + + moduleFile << std::endl; + } + + if (!_loader.isIntrospection()) + { + pendingSeparator.reset(); + + moduleFile << R"cpp(using Operations = included::Operations; + +)cpp"; + } + + if (!_loader.getInterfaceTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& interfaceType : _loader.getInterfaceTypes()) + { + moduleFile << R"cpp(void Add)cpp" << interfaceType.cppType + << R"cpp(Details(const std::shared_ptr& type)cpp" + << interfaceType.cppType + << R"cpp(, const std::shared_ptr& schema) +{ + included::Add)cpp" << interfaceType.cppType + << R"cpp(Details(type)cpp" << interfaceType.cppType << R"cpp(, schema); +} + +)cpp"; + } + } + + if (!_loader.getUnionTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& unionType : _loader.getUnionTypes()) + { + moduleFile << R"cpp(void Add)cpp" << unionType.cppType + << R"cpp(Details(const std::shared_ptr& type)cpp" + << unionType.cppType + << R"cpp(, const std::shared_ptr& schema) +{ + included::Add)cpp" << unionType.cppType + << R"cpp(Details(type)cpp" << unionType.cppType << R"cpp(, schema); +} + +)cpp"; + } + } + + if (!_loader.getObjectTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& objectType : _loader.getObjectTypes()) + { + moduleFile << R"cpp(void Add)cpp" << objectType.cppType + << R"cpp(Details(const std::shared_ptr& type)cpp" + << objectType.cppType + << R"cpp(, const std::shared_ptr& schema) +{ + included::Add)cpp" << objectType.cppType + << R"cpp(Details(type)cpp" << objectType.cppType << R"cpp(, schema); +} + +)cpp"; + } + } + + if (_loader.isIntrospection()) + { + pendingSeparator.reset(); + moduleFile << R"cpp(void AddTypesToSchema(const std::shared_ptr& schema) +{ + included::AddTypesToSchema(schema); +} + +)cpp"; + } + else + { + pendingSeparator.reset(); + moduleFile << R"cpp(std::shared_ptr GetSchema() +{ + return included::GetSchema(); +} + +)cpp"; + } + + if (exportedNamespace.exit()) + { + moduleFile << R"cpp( +using namespace exported; + +)cpp"; + } + + return true; +} + void Generator::outputInterfaceDeclaration(std::ostream& headerFile, std::string_view cppType) const { headerFile @@ -745,6 +934,42 @@ void Generator::outputInterfaceDeclaration(std::ostream& headerFile, std::string )cpp"; } +void Generator::outputObjectModule( + std::ostream& moduleFile, std::string_view objectNamespace, std::string_view cppType) const +{ + moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include ")cpp" << cppType + << R"cpp(Object.h" + +export module GraphQL.)cpp" + << _loader.getFilenamePrefix() << R"cpp(.)cpp" << cppType << R"cpp(Object; + +namespace included = )cpp" + << objectNamespace << R"cpp(; + +export namespace )cpp" + << objectNamespace << R"cpp( { + +namespace exported { + +using )cpp" << cppType + << R"cpp( = included::)cpp" << cppType << R"cpp(; + +} // namespace exported + +using namespace exported; + +} // namespace )cpp" + << objectNamespace << R"cpp( +)cpp"; +} + void Generator::outputObjectImplements(std::ostream& headerFile, const ObjectType& objectType) const { headerFile << R"cpp(template @@ -3054,11 +3279,21 @@ std::vector Generator::outputSeparateFiles() const noexcept headerFile << std::endl; outputInterfaceDeclaration(headerFile, interfaceType.cppType); headerFile << std::endl; + } - if (_options.verbose) - { - files.push_back(std::move(headerPath)); - } + const auto moduleFilename = std::string(interfaceType.cppType) + "Object.ixx"; + auto modulePath = (headerDir / moduleFilename).string(); + + { + std::ofstream moduleFile(modulePath, std::ios_base::trunc); + + outputObjectModule(moduleFile, objectNamespace, interfaceType.cppType); + } + + if (_options.verbose) + { + files.push_back(std::move(headerPath)); + files.push_back(std::move(modulePath)); } const auto sourceFilename = std::string(interfaceType.cppType) + "Object.cpp"; @@ -3130,9 +3365,19 @@ using namespace std::literals; headerFile << std::endl; } + const auto moduleFilename = std::string(unionType.cppType) + "Object.ixx"; + auto modulePath = (headerDir / moduleFilename).string(); + + { + std::ofstream moduleFile(modulePath, std::ios_base::trunc); + + outputObjectModule(moduleFile, objectNamespace, unionType.cppType); + } + if (_options.verbose) { files.push_back(std::move(headerPath)); + files.push_back(std::move(modulePath)); } const auto sourceFilename = std::string(unionType.cppType) + "Object.cpp"; @@ -3229,9 +3474,19 @@ using namespace std::literals; headerFile << std::endl; } + const auto moduleFilename = std::string(objectType.cppType) + "Object.ixx"; + auto modulePath = (headerDir / moduleFilename).string(); + + { + std::ofstream moduleFile(modulePath, std::ios_base::trunc); + + outputObjectModule(moduleFile, objectNamespace, objectType.cppType); + } + if (_options.verbose) { files.push_back(std::move(headerPath)); + files.push_back(std::move(modulePath)); } const auto sourceFilename = std::string(objectType.cppType) + "Object.cpp"; diff --git a/src/introspection/CMakeLists.txt b/src/introspection/CMakeLists.txt index 841bbb9f..a30faa97 100644 --- a/src/introspection/CMakeLists.txt +++ b/src/introspection/CMakeLists.txt @@ -10,11 +10,12 @@ if(GRAPHQL_UPDATE_SAMPLES) update_graphql_schema_files(introspection schema.introspection.graphql Introspection introspection --introspection) file(GLOB PRIVATE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) + file(GLOB PRIVATE_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) add_custom_command( OUTPUT copied_introspection_schema_headers - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PRIVATE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/../../include/graphqlservice/introspection/ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PRIVATE_HEADERS} ${PRIVATE_MODULES} ${CMAKE_CURRENT_SOURCE_DIR}/../../include/graphqlservice/introspection/ COMMAND ${CMAKE_COMMAND} -E touch copied_introspection_schema_headers - DEPENDS ${PRIVATE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/introspection_schema_files + DEPENDS ${PRIVATE_HEADERS} ${PRIVATE_MODULES} ${CMAKE_CURRENT_SOURCE_DIR}/introspection_schema_files COMMENT "Updating IntrospectionSchema headers") add_custom_target(copy_introspection_schema_headers ALL diff --git a/src/introspection/DirectiveObject.ixx b/src/introspection/DirectiveObject.ixx new file mode 100644 index 00000000..3074c61c --- /dev/null +++ b/src/introspection/DirectiveObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "DirectiveObject.h" + +export module GraphQL.Introspection.DirectiveObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using Directive = included::Directive; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/src/introspection/EnumValueObject.ixx b/src/introspection/EnumValueObject.ixx new file mode 100644 index 00000000..3fe1aac9 --- /dev/null +++ b/src/introspection/EnumValueObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "EnumValueObject.h" + +export module GraphQL.Introspection.EnumValueObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using EnumValue = included::EnumValue; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/src/introspection/FieldObject.ixx b/src/introspection/FieldObject.ixx new file mode 100644 index 00000000..6458133e --- /dev/null +++ b/src/introspection/FieldObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FieldObject.h" + +export module GraphQL.Introspection.FieldObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using Field = included::Field; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/src/introspection/InputValueObject.ixx b/src/introspection/InputValueObject.ixx new file mode 100644 index 00000000..ffa0ce4e --- /dev/null +++ b/src/introspection/InputValueObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "InputValueObject.h" + +export module GraphQL.Introspection.InputValueObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using InputValue = included::InputValue; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/src/introspection/IntrospectionSchema.ixx b/src/introspection/IntrospectionSchema.ixx new file mode 100644 index 00000000..859747cb --- /dev/null +++ b/src/introspection/IntrospectionSchema.ixx @@ -0,0 +1,81 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "IntrospectionSchema.h" + +export module GraphQL.Introspection.IntrospectionSchema; + +namespace included = graphql::introspection; + +export namespace graphql::introspection { + +namespace exported { + +using TypeKind = included::TypeKind; + +constexpr auto getTypeKindNames() noexcept +{ + return included::getTypeKindNames(); +} + +constexpr auto getTypeKindValues() noexcept +{ + return included::getTypeKindValues(); +} + +using DirectiveLocation = included::DirectiveLocation; + +constexpr auto getDirectiveLocationNames() noexcept +{ + return included::getDirectiveLocationNames(); +} + +constexpr auto getDirectiveLocationValues() noexcept +{ + return included::getDirectiveLocationValues(); +} + +void AddSchemaDetails(const std::shared_ptr& typeSchema, const std::shared_ptr& schema) +{ + included::AddSchemaDetails(typeSchema, schema); +} + +void AddTypeDetails(const std::shared_ptr& typeType, const std::shared_ptr& schema) +{ + included::AddTypeDetails(typeType, schema); +} + +void AddFieldDetails(const std::shared_ptr& typeField, const std::shared_ptr& schema) +{ + included::AddFieldDetails(typeField, schema); +} + +void AddInputValueDetails(const std::shared_ptr& typeInputValue, const std::shared_ptr& schema) +{ + included::AddInputValueDetails(typeInputValue, schema); +} + +void AddEnumValueDetails(const std::shared_ptr& typeEnumValue, const std::shared_ptr& schema) +{ + included::AddEnumValueDetails(typeEnumValue, schema); +} + +void AddDirectiveDetails(const std::shared_ptr& typeDirective, const std::shared_ptr& schema) +{ + included::AddDirectiveDetails(typeDirective, schema); +} + +void AddTypesToSchema(const std::shared_ptr& schema) +{ + included::AddTypesToSchema(schema); +} + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection diff --git a/src/introspection/SchemaObject.ixx b/src/introspection/SchemaObject.ixx new file mode 100644 index 00000000..b96287b2 --- /dev/null +++ b/src/introspection/SchemaObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SchemaObject.h" + +export module GraphQL.Introspection.SchemaObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using Schema = included::Schema; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object diff --git a/src/introspection/TypeObject.ixx b/src/introspection/TypeObject.ixx new file mode 100644 index 00000000..1c16e7a1 --- /dev/null +++ b/src/introspection/TypeObject.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TypeObject.h" + +export module GraphQL.Introspection.TypeObject; + +namespace included = graphql::introspection::object; + +export namespace graphql::introspection::object { + +namespace exported { + +using Type = included::Type; + +} // namespace exported + +using namespace exported; + +} // namespace graphql::introspection::object From d68dbcca6661dd8f8123f697b7d572942ad41fa1 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 10:34:15 -0700 Subject: [PATCH 033/123] feat(modules): generate public interface modules in clientgen --- cmake/cppgraphqlgen-functions.cmake | 14 ++ cmake/cppgraphqlgen-update-client-files.cmake | 8 +- include/ClientGenerator.h | 4 + samples/client/benchmark/BenchmarkClient.ixx | 28 ++++ .../client/multiple/MultipleQueriesClient.ixx | 60 +++++++ samples/client/mutate/MutateClient.ixx | 36 ++++ .../client/nestedinput/NestedInputClient.ixx | 33 ++++ samples/client/query/QueryClient.ixx | 34 ++++ samples/client/subscribe/SubscribeClient.ixx | 28 ++++ samples/proxy/query/ProxyClient.ixx | 28 ++++ src/ClientGenerator.cpp | 156 ++++++++++++++++++ 11 files changed, 425 insertions(+), 4 deletions(-) create mode 100644 samples/client/benchmark/BenchmarkClient.ixx create mode 100644 samples/client/multiple/MultipleQueriesClient.ixx create mode 100644 samples/client/mutate/MutateClient.ixx create mode 100644 samples/client/nestedinput/NestedInputClient.ixx create mode 100644 samples/client/query/QueryClient.ixx create mode 100644 samples/client/subscribe/SubscribeClient.ixx create mode 100644 samples/proxy/query/ProxyClient.ixx diff --git a/cmake/cppgraphqlgen-functions.cmake b/cmake/cppgraphqlgen-functions.cmake index e37a02e0..15e3e7e9 100644 --- a/cmake/cppgraphqlgen-functions.cmake +++ b/cmake/cppgraphqlgen-functions.cmake @@ -100,9 +100,23 @@ function(add_graphql_client_target CLIENT_TARGET) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${CLIENT_TARGET}_client_files) file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${CLIENT_TARGET}_client_files CLIENT_FILES) + file(GLOB CLIENT_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) + file(GLOB CLIENT_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) add_library(${CLIENT_TARGET}_client STATIC ${CLIENT_FILES}) add_dependencies(${CLIENT_TARGET}_client ${CLIENT_TARGET}_update_client) + target_compile_features(${CLIENT_TARGET}_client PUBLIC cxx_std_20) target_include_directories(${CLIENT_TARGET}_client PUBLIC $) target_link_libraries(${CLIENT_TARGET}_client PUBLIC cppgraphqlgen::graphqlclient) + target_sources(${CLIENT_TARGET}_client + PUBLIC FILE_SET HEADERS + BASE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${CLIENT_HEADERS} + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${CLIENT_MODULES}) endif() endfunction() diff --git a/cmake/cppgraphqlgen-update-client-files.cmake b/cmake/cppgraphqlgen-update-client-files.cmake index 1ab6fcb1..c9d5934d 100644 --- a/cmake/cppgraphqlgen-update-client-files.cmake +++ b/cmake/cppgraphqlgen-update-client-files.cmake @@ -11,7 +11,7 @@ get_filename_component(REQUEST_GRAPHQL "${CLIENT_SOURCE_DIR}/${REQUEST_GRAPHQL}" file(MAKE_DIRECTORY ${CLIENT_BINARY_DIR}) # Cleanup all of the stale files in the binary directory -file(GLOB PREVIOUS_FILES ${CLIENT_BINARY_DIR}/*.h ${CLIENT_BINARY_DIR}/*.cpp +file(GLOB PREVIOUS_FILES ${CLIENT_BINARY_DIR}/*.h ${CLIENT_BINARY_DIR}/*.ixx ${CLIENT_BINARY_DIR}/*.cpp ${CLIENT_BINARY_DIR}/${CLIENT_TARGET}_client_files) foreach(PREVIOUS_FILE ${PREVIOUS_FILES}) file(REMOVE ${PREVIOUS_FILE}) @@ -30,7 +30,7 @@ execute_process( # Get the up-to-date list of files in the binary directory set(FILE_NAMES "") -file(GLOB NEW_FILES ${CLIENT_BINARY_DIR}/*.h ${CLIENT_BINARY_DIR}/*.cpp) +file(GLOB NEW_FILES ${CLIENT_BINARY_DIR}/*.h ${CLIENT_BINARY_DIR}/*.ixx ${CLIENT_BINARY_DIR}/*.cpp) foreach(NEW_FILE ${NEW_FILES}) get_filename_component(NEW_FILE ${NEW_FILE} NAME) list(APPEND FILE_NAMES "${NEW_FILE}") @@ -45,11 +45,11 @@ endif() cmake_policy(SET CMP0057 NEW) # Remove stale files in the source directory -file(GLOB OLD_FILES ${CLIENT_SOURCE_DIR}/*.h ${CLIENT_SOURCE_DIR}/*.cpp) +file(GLOB OLD_FILES ${CLIENT_SOURCE_DIR}/*.h ${CLIENT_SOURCE_DIR}/*.ixx ${CLIENT_SOURCE_DIR}/*.cpp) foreach(OLD_FILE ${OLD_FILES}) get_filename_component(OLD_FILE ${OLD_FILE} NAME) if(NOT OLD_FILE IN_LIST FILE_NAMES) - if(OLD_FILE MATCHES "Client\\.h$" OR OLD_FILE MATCHES "Client\\.cpp$") + if(OLD_FILE MATCHES "Client\\.h$" OR OLD_FILE MATCHES "Client\\.ixx$" OR OLD_FILE MATCHES "Client\\.cpp$") file(REMOVE "${CLIENT_SOURCE_DIR}/${OLD_FILE}") else() message(WARNING "Unexpected file in ${CLIENT_TARGET} client sources: ${OLD_FILE}") diff --git a/include/ClientGenerator.h b/include/ClientGenerator.h index 2b3af1f2..4070a12f 100644 --- a/include/ClientGenerator.h +++ b/include/ClientGenerator.h @@ -39,6 +39,7 @@ class [[nodiscard("unnecessary construction")]] Generator [[nodiscard("unnecessary memory copy")]] std::string getHeaderDir() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSourceDir() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getHeaderPath() const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getModulePath() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSourcePath() const noexcept; [[nodiscard("unnecessary call")]] const std::string& getClientNamespace() const noexcept; [[nodiscard("unnecessary call")]] const std::string& getOperationNamespace( @@ -53,6 +54,8 @@ class [[nodiscard("unnecessary construction")]] Generator [[nodiscard("unnecessary call")]] bool outputResponseFieldType(std::ostream& headerFile, const ResponseField& responseField, std::size_t indent = 0) const noexcept; + [[nodiscard("unnecessary call")]] bool outputModule() const noexcept; + [[nodiscard("unnecessary call")]] bool outputSource() const noexcept; void outputGetRequestImplementation(std::ostream& sourceFile) const noexcept; void outputGetOperationNameImplementation( @@ -68,6 +71,7 @@ class [[nodiscard("unnecessary construction")]] Generator const std::string _headerDir; const std::string _sourceDir; const std::string _headerPath; + const std::string _modulePath; const std::string _sourcePath; }; diff --git a/samples/client/benchmark/BenchmarkClient.ixx b/samples/client/benchmark/BenchmarkClient.ixx new file mode 100644 index 00000000..eb7d9ea0 --- /dev/null +++ b/samples/client/benchmark/BenchmarkClient.ixx @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "BenchmarkClient.h" + +export module GraphQL.Benchmark.BenchmarkClient; + +namespace included = graphql::client; + +export namespace graphql::client { + +namespace exported { + +namespace query::Query { + +using Traits = included::query::Query::Traits; + +} // namespace query::Query + +} // namespace exported + +using namespace exported; + +} // namespace graphql::client diff --git a/samples/client/multiple/MultipleQueriesClient.ixx b/samples/client/multiple/MultipleQueriesClient.ixx new file mode 100644 index 00000000..074fbd7f --- /dev/null +++ b/samples/client/multiple/MultipleQueriesClient.ixx @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MultipleQueriesClient.h" + +export module GraphQL.MultipleQueries.MultipleQueriesClient; + +namespace included = graphql::client; + +export namespace graphql::client { + +namespace exported { + +namespace multiple { + +using TaskState = included::multiple::TaskState; + +using CompleteTaskInput = included::multiple::CompleteTaskInput; + +} // namespace multiple + +namespace query::Appointments { + +using Traits = included::query::Appointments::Traits; + +} // namespace query::Appointments + +namespace query::Tasks { + +using Traits = included::query::Tasks::Traits; + +} // namespace query::Tasks + +namespace query::UnreadCounts { + +using Traits = included::query::UnreadCounts::Traits; + +} // namespace query::UnreadCounts + +namespace query::Miscellaneous { + +using Traits = included::query::Miscellaneous::Traits; + +} // namespace query::Miscellaneous + +namespace mutation::CompleteTaskMutation { + +using Traits = included::mutation::CompleteTaskMutation::Traits; + +} // namespace mutation::CompleteTaskMutation + +} // namespace exported + +using namespace exported; + +} // namespace graphql::client diff --git a/samples/client/mutate/MutateClient.ixx b/samples/client/mutate/MutateClient.ixx new file mode 100644 index 00000000..4ffa4c81 --- /dev/null +++ b/samples/client/mutate/MutateClient.ixx @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutateClient.h" + +export module GraphQL.Mutate.MutateClient; + +namespace included = graphql::client; + +export namespace graphql::client { + +namespace exported { + +namespace mutate { + +using TaskState = included::mutate::TaskState; + +using CompleteTaskInput = included::mutate::CompleteTaskInput; + +} // namespace mutate + +namespace mutation::CompleteTaskMutation { + +using Traits = included::mutation::CompleteTaskMutation::Traits; + +} // namespace mutation::CompleteTaskMutation + +} // namespace exported + +using namespace exported; + +} // namespace graphql::client diff --git a/samples/client/nestedinput/NestedInputClient.ixx b/samples/client/nestedinput/NestedInputClient.ixx new file mode 100644 index 00000000..197b8ea2 --- /dev/null +++ b/samples/client/nestedinput/NestedInputClient.ixx @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NestedInputClient.h" + +export module GraphQL.NestedInput.NestedInputClient; + +namespace included = graphql::client; + +export namespace graphql::client { + +namespace exported { + +using InputA = included::nestedinput::InputA; +using InputB = included::nestedinput::InputB; +using InputABCD = included::nestedinput::InputABCD; +using InputBC = included::nestedinput::InputBC; + +namespace query::testQuery { + +using Traits = included::query::testQuery::Traits; + +} // namespace query::testQuery + +} // namespace exported + +using namespace exported; + +} // namespace graphql::client diff --git a/samples/client/query/QueryClient.ixx b/samples/client/query/QueryClient.ixx new file mode 100644 index 00000000..660a2afd --- /dev/null +++ b/samples/client/query/QueryClient.ixx @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryClient.h" + +export module GraphQL.Query.QueryClient; + +namespace included = graphql::client; + +export namespace graphql::client { + +namespace exported { + +namespace query { + +using TaskState = included::query::TaskState; + +} // namespace query + +namespace query::Query { + +using Traits = included::query::Query::Traits; + +} // namespace query::Query + +} // namespace exported + +using namespace exported; + +} // namespace graphql::client diff --git a/samples/client/subscribe/SubscribeClient.ixx b/samples/client/subscribe/SubscribeClient.ixx new file mode 100644 index 00000000..3cba1362 --- /dev/null +++ b/samples/client/subscribe/SubscribeClient.ixx @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SubscribeClient.h" + +export module GraphQL.Subscribe.SubscribeClient; + +namespace included = graphql::client; + +export namespace graphql::client { + +namespace exported { + +namespace subscription::TestSubscription { + +using Traits = included::subscription::TestSubscription::Traits; + +} // namespace subscription::TestSubscription + +} // namespace exported + +using namespace exported; + +} // namespace graphql::client diff --git a/samples/proxy/query/ProxyClient.ixx b/samples/proxy/query/ProxyClient.ixx new file mode 100644 index 00000000..4593cade --- /dev/null +++ b/samples/proxy/query/ProxyClient.ixx @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ProxyClient.h" + +export module GraphQL.Proxy.ProxyClient; + +namespace included = graphql::client; + +export namespace graphql::client { + +namespace exported { + +namespace query::relayQuery { + +using Traits = included::query::relayQuery::Traits; + +} // namespace query::relayQuery + +} // namespace exported + +using namespace exported; + +} // namespace graphql::client diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 1c3f43d0..cba1b99b 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -39,6 +39,7 @@ Generator::Generator( , _headerDir(getHeaderDir()) , _sourceDir(getSourceDir()) , _headerPath(getHeaderPath()) + , _modulePath(getModulePath()) , _sourcePath(getSourcePath()) { } @@ -76,6 +77,15 @@ std::string Generator::getHeaderPath() const noexcept return fullPath.string(); } +std::string Generator::getModulePath() const noexcept +{ + std::filesystem::path fullPath { _headerDir }; + + fullPath /= (std::string { _schemaLoader.getFilenamePrefix() } + "Client.ixx"); + + return fullPath.string(); +} + std::string Generator::getSourcePath() const noexcept { std::filesystem::path fullPath { _sourceDir }; @@ -155,6 +165,11 @@ std::vector Generator::Build() const noexcept builtFiles.push_back(_headerPath); } + if (outputModule() && _options.verbose) + { + builtFiles.push_back(_modulePath); + } + if (outputSource()) { builtFiles.push_back(_sourcePath); @@ -600,6 +615,147 @@ bool Generator::outputResponseFieldType(std::ostream& headerFile, return true; } +bool Generator::outputModule() const noexcept +{ + std::ofstream moduleFile(_modulePath, std::ios_base::trunc); + std::ostringstream ossNamespace; + + ossNamespace << getClientNamespace() << R"cpp(::)cpp"; + + const auto clientNamespace = ossNamespace.str(); + + moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include ")cpp" << _schemaLoader.getFilenamePrefix() + << + R"cpp(Client.h" + +export module GraphQL.)cpp" + << _schemaLoader.getFilenamePrefix() << R"cpp(.)cpp" + << _schemaLoader.getFilenamePrefix() << + R"cpp(Client; + +namespace included = )cpp" + << getClientNamespace() << R"cpp(; + +export )cpp"; + + NamespaceScope graphqlNamespace { moduleFile, getClientNamespace() }; + + moduleFile << std::endl; + + NamespaceScope exportedNamespace { moduleFile, "exported" }; + NamespaceScope schemaNamespace { moduleFile, _schemaLoader.getSchemaNamespace(), true }; + PendingBlankLine pendingSeparator { moduleFile }; + + const auto& operations = _requestLoader.getOperations(); + std::unordered_set declaredEnum; + + for (const auto& operation : operations) + { + if (!_requestLoader.getReferencedEnums(operation).empty()) + { + pendingSeparator.reset(); + + // Define all of the enums referenced either in variables or the response. + for (const auto& enumType : _requestLoader.getReferencedEnums(operation)) + { + const auto cppType = _schemaLoader.getCppType(enumType->name()); + + if (!declaredEnum.insert(cppType).second) + { + continue; + } + + if (schemaNamespace.enter()) + { + moduleFile << std::endl; + } + + moduleFile << R"cpp(using )cpp" << cppType << R"cpp( = included::)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << cppType + << R"cpp(; +)cpp"; + } + } + } + + if (!declaredEnum.empty()) + { + pendingSeparator.add(); + } + + std::unordered_set declaredInput; + std::unordered_set forwardDeclaredInput; + + for (const auto& operation : operations) + { + if (!_requestLoader.getReferencedInputTypes(operation).empty()) + { + pendingSeparator.reset(); + + // Define all of the input object structs referenced in variables. + for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) + { + const auto cppType = _schemaLoader.getCppType(inputType.type->name()); + + if (!declaredInput.insert(cppType).second) + { + continue; + } + + moduleFile << R"cpp(using )cpp" << cppType << R"cpp( = included::)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << cppType + << R"cpp(; +)cpp"; + } + } + } + + if (!declaredInput.empty()) + { + pendingSeparator.add(); + } + + pendingSeparator.reset(); + if (schemaNamespace.exit()) + { + pendingSeparator.add(); + } + + for (const auto& operation : operations) + { + pendingSeparator.reset(); + + NamespaceScope operationNamespaceScope { moduleFile, getOperationNamespace(operation) }; + + moduleFile << R"cpp( +using Traits = included::)cpp" + << getOperationNamespace(operation) << R"cpp(::Traits; + +)cpp"; + + pendingSeparator.add(); + } + + pendingSeparator.reset(); + + if (exportedNamespace.exit()) + { + moduleFile << R"cpp( +using namespace exported; + +)cpp"; + } + + return true; +} + bool Generator::outputSource() const noexcept { std::ofstream sourceFile(_sourcePath, std::ios_base::trunc); From 954520c2f973e2be92f5c6eddab2b994e57ec29e Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 12:12:38 -0700 Subject: [PATCH 034/123] fix(modules): simplify exports with using statements --- include/graphqlservice/internal/Awaitable.ixx | 5 +- include/graphqlservice/internal/Base64.ixx | 4 +- include/graphqlservice/internal/Grammar.ixx | 503 +++++++++--------- .../graphqlservice/internal/Introspection.ixx | 14 +- include/graphqlservice/internal/Schema.ixx | 36 +- include/graphqlservice/internal/SortedMap.ixx | 40 +- .../graphqlservice/internal/SyntaxTree.ixx | 4 +- .../introspection/DirectiveObject.ixx | 2 +- .../introspection/EnumValueObject.ixx | 2 +- .../introspection/FieldObject.ixx | 2 +- .../introspection/InputValueObject.ixx | 2 +- .../introspection/IntrospectionSchema.ixx | 74 +-- .../introspection/SchemaObject.ixx | 2 +- .../introspection/TypeObject.ixx | 2 +- samples/client/benchmark/BenchmarkClient.ixx | 16 +- .../client/multiple/MultipleQueriesClient.ixx | 61 ++- samples/client/mutate/MutateClient.ixx | 23 +- .../client/nestedinput/NestedInputClient.ixx | 32 +- samples/client/query/QueryClient.ixx | 16 +- samples/client/subscribe/SubscribeClient.ixx | 16 +- samples/learn/schema/CharacterObject.ixx | 2 +- samples/learn/schema/DroidObject.ixx | 2 +- samples/learn/schema/HumanObject.ixx | 2 +- samples/learn/schema/MutationObject.ixx | 2 +- samples/learn/schema/QueryObject.ixx | 2 +- samples/learn/schema/ReviewObject.ixx | 2 +- samples/learn/schema/StarWarsSchema.ixx | 58 +- samples/proxy/query/ProxyClient.ixx | 19 +- samples/proxy/schema/ProxySchema.ixx | 12 +- samples/proxy/schema/QueryObject.ixx | 2 +- .../AppointmentConnectionObject.ixx | 2 +- .../nointrospection/AppointmentEdgeObject.ixx | 2 +- .../nointrospection/AppointmentObject.ixx | 2 +- .../CompleteTaskPayloadObject.ixx | 2 +- .../today/nointrospection/ExpensiveObject.ixx | 2 +- .../FolderConnectionObject.ixx | 2 +- .../nointrospection/FolderEdgeObject.ixx | 2 +- .../today/nointrospection/FolderObject.ixx | 2 +- .../today/nointrospection/MutationObject.ixx | 2 +- .../nointrospection/NestedTypeObject.ixx | 2 +- samples/today/nointrospection/NodeObject.ixx | 2 +- .../today/nointrospection/PageInfoObject.ixx | 2 +- samples/today/nointrospection/QueryObject.ixx | 2 +- .../nointrospection/SubscriptionObject.ixx | 2 +- .../nointrospection/TaskConnectionObject.ixx | 2 +- .../today/nointrospection/TaskEdgeObject.ixx | 2 +- samples/today/nointrospection/TaskObject.ixx | 2 +- samples/today/nointrospection/TodaySchema.ixx | 154 ++---- .../today/nointrospection/UnionTypeObject.ixx | 2 +- .../schema/AppointmentConnectionObject.ixx | 2 +- .../today/schema/AppointmentEdgeObject.ixx | 2 +- samples/today/schema/AppointmentObject.ixx | 2 +- .../schema/CompleteTaskPayloadObject.ixx | 2 +- samples/today/schema/ExpensiveObject.ixx | 2 +- .../today/schema/FolderConnectionObject.ixx | 2 +- samples/today/schema/FolderEdgeObject.ixx | 2 +- samples/today/schema/FolderObject.ixx | 2 +- samples/today/schema/MutationObject.ixx | 2 +- samples/today/schema/NestedTypeObject.ixx | 2 +- samples/today/schema/NodeObject.ixx | 2 +- samples/today/schema/PageInfoObject.ixx | 2 +- samples/today/schema/QueryObject.ixx | 2 +- samples/today/schema/SubscriptionObject.ixx | 2 +- samples/today/schema/TaskConnectionObject.ixx | 2 +- samples/today/schema/TaskEdgeObject.ixx | 2 +- samples/today/schema/TaskObject.ixx | 2 +- samples/today/schema/TodaySchema.ixx | 154 ++---- samples/today/schema/UnionTypeObject.ixx | 2 +- samples/validation/schema/AlienObject.ixx | 2 +- samples/validation/schema/ArgumentsObject.ixx | 2 +- samples/validation/schema/CatObject.ixx | 2 +- samples/validation/schema/CatOrDogObject.ixx | 2 +- samples/validation/schema/DogObject.ixx | 2 +- .../validation/schema/DogOrHumanObject.ixx | 2 +- samples/validation/schema/HumanObject.ixx | 2 +- .../validation/schema/HumanOrAlienObject.ixx | 2 +- samples/validation/schema/MessageObject.ixx | 2 +- .../schema/MutateDogResultObject.ixx | 2 +- samples/validation/schema/MutationObject.ixx | 2 +- samples/validation/schema/NodeObject.ixx | 2 +- samples/validation/schema/PetObject.ixx | 2 +- samples/validation/schema/QueryObject.ixx | 2 +- samples/validation/schema/ResourceObject.ixx | 2 +- samples/validation/schema/SentientObject.ixx | 2 +- .../validation/schema/SubscriptionObject.ixx | 2 +- .../validation/schema/ValidationSchema.ixx | 148 ++---- src/ClientGenerator.cpp | 83 ++- src/SchemaGenerator.cpp | 74 +-- src/introspection/DirectiveObject.ixx | 2 +- src/introspection/EnumValueObject.ixx | 2 +- src/introspection/FieldObject.ixx | 2 +- src/introspection/InputValueObject.ixx | 2 +- src/introspection/IntrospectionSchema.ixx | 74 +-- src/introspection/SchemaObject.ixx | 2 +- src/introspection/TypeObject.ixx | 2 +- 95 files changed, 759 insertions(+), 1005 deletions(-) diff --git a/include/graphqlservice/internal/Awaitable.ixx b/include/graphqlservice/internal/Awaitable.ixx index 052f52f0..c0ff337b 100644 --- a/include/graphqlservice/internal/Awaitable.ixx +++ b/include/graphqlservice/internal/Awaitable.ixx @@ -13,8 +13,9 @@ export namespace graphql::internal { namespace exported { -template -using Awaitable = included::Awaitable; +// clang-format off +using included::Awaitable; +// clang-format on } // namespace exported diff --git a/include/graphqlservice/internal/Base64.ixx b/include/graphqlservice/internal/Base64.ixx index 067bd14e..5b1b9ecc 100644 --- a/include/graphqlservice/internal/Base64.ixx +++ b/include/graphqlservice/internal/Base64.ixx @@ -13,7 +13,9 @@ export namespace graphql::internal { namespace exported { -using Base64 = included::Base64; +// clang-format off +using included::Base64; +// clang-format on } // namespace exported diff --git a/include/graphqlservice/internal/Grammar.ixx b/include/graphqlservice/internal/Grammar.ixx index 9ca69005..66c655a3 100644 --- a/include/graphqlservice/internal/Grammar.ixx +++ b/include/graphqlservice/internal/Grammar.ixx @@ -13,272 +13,249 @@ export namespace graphql::peg { namespace exported { +// clang-format off using namespace tao::graphqlpeg; -template -inline void for_each_child(const ast_node& n, std::function&& func) -{ - included::for_each_child(n, std::move(func)); -} +using included::for_each_child; +using included::on_first_child; +using included::on_first_child_if; -template -inline void on_first_child_if(const ast_node& n, std::function&& func) -{ - included::on_first_child_if(n, std::move(func)); -} - -template -inline void on_first_child(const ast_node& n, std::function&& func) -{ - included::on_first_child(n, std::move(func)); -} - -using source_character = included::source_character; -using comment = included::comment; -using ignored = included::ignored; -using name = included::name; -using variable_name_content = included::variable_name_content; -using variable_name = included::variable_name; -using null_keyword = included::null_keyword; -using quote_token = included::quote_token; -using backslash_token = included::backslash_token; -using escaped_unicode_codepoint = included::escaped_unicode_codepoint; -using escaped_unicode_content = included::escaped_unicode_content; -using escaped_unicode = included::escaped_unicode; -using escaped_char = included::escaped_char; -using string_escape_sequence_content = included::string_escape_sequence_content; -using string_escape_sequence = included::string_escape_sequence; -using string_quote_character = included::string_quote_character; -using string_quote_content = included::string_quote_content; -using string_quote = included::string_quote; -using block_quote_token = included::block_quote_token; -using block_escape_sequence = included::block_escape_sequence; -using block_quote_character = included::block_quote_character; -using block_quote_empty_line = included::block_quote_empty_line; -using block_quote_line_content = included::block_quote_line_content; -using block_quote_line = included::block_quote_line; -using block_quote_content_lines = included::block_quote_content_lines; -using block_quote_content = included::block_quote_content; -using block_quote = included::block_quote; -using string_value = included::string_value; -using nonzero_digit = included::nonzero_digit; -using zero_digit = included::zero_digit; -using negative_sign = included::negative_sign; -using integer_part = included::integer_part; -using integer_value = included::integer_value; -using fractional_part_content = included::fractional_part_content; -using fractional_part = included::fractional_part; -using exponent_indicator = included::exponent_indicator; -using sign = included::sign; -using exponent_part_content = included::exponent_part_content; -using exponent_part = included::exponent_part; -using float_value = included::float_value; -using true_keyword = included::true_keyword; -using false_keyword = included::false_keyword; -using bool_value = included::bool_value; -using enum_value = included::enum_value; -using operation_type = included::operation_type; -using alias_name = included::alias_name; -using alias = included::alias; -using argument_name = included::argument_name; -using argument_content = included::argument_content; -using argument = included::argument; -using arguments_content = included::arguments_content; -using arguments = included::arguments; -using list_value_content = included::list_value_content; -using list_value = included::list_value; -using object_field_name = included::object_field_name; -using object_field_content = included::object_field_content; -using object_field = included::object_field; -using object_value_content = included::object_value_content; -using object_value = included::object_value; -using variable_value = included::variable_value; -using input_value_content = included::input_value_content; -using input_value = included::input_value; -using list_entry = included::list_entry; -using default_value_content = included::default_value_content; -using default_value = included::default_value; -using named_type = included::named_type; -using list_type_content = included::list_type_content; -using list_type = included::list_type; -using nonnull_type = included::nonnull_type; -using type_name_content = included::type_name_content; -using type_name = included::type_name; -using variable_content = included::variable_content; -using variable = included::variable; -using variable_definitions_content = included::variable_definitions_content; -using variable_definitions = included::variable_definitions; -using directive_name = included::directive_name; -using directive_content = included::directive_content; -using directive = included::directive; -using directives = included::directives; -using field_name = included::field_name; -using field_start = included::field_start; -using field_arguments = included::field_arguments; -using field_directives = included::field_directives; -using field_selection_set = included::field_selection_set; -using field_content = included::field_content; -using field = included::field; -using on_keyword = included::on_keyword; -using fragment_name = included::fragment_name; -using fragment_token = included::fragment_token; -using fragment_spread = included::fragment_spread; -using type_condition_content = included::type_condition_content; -using type_condition = included::type_condition; -using inline_fragment = included::inline_fragment; -using fragement_spread_or_inline_fragment_content = - included::fragement_spread_or_inline_fragment_content; -using fragement_spread_or_inline_fragment = included::fragement_spread_or_inline_fragment; -using selection = included::selection; -using selection_set_content = included::selection_set_content; -using selection_set = included::selection_set; -using operation_name = included::operation_name; -using operation_definition_operation_type_content = - included::operation_definition_operation_type_content; -using operation_definition = included::operation_definition; -using fragment_definition_content = included::fragment_definition_content; -using fragment_definition = included::fragment_definition; -using executable_definition = included::executable_definition; -using description = included::description; -using schema_keyword = included::schema_keyword; -using root_operation_definition_content = included::root_operation_definition_content; -using root_operation_definition = included::root_operation_definition; -using schema_definition_start = included::schema_definition_start; -using schema_definition_content = included::schema_definition_content; -using schema_definition = included::schema_definition; -using scalar_keyword = included::scalar_keyword; -using scalar_name = included::scalar_name; -using scalar_type_definition_start = included::scalar_type_definition_start; -using scalar_type_definition_content = included::scalar_type_definition_content; -using scalar_type_definition = included::scalar_type_definition; -using type_keyword = included::type_keyword; -using arguments_definition_start = included::arguments_definition_start; -using arguments_definition_content = included::arguments_definition_content; -using arguments_definition = included::arguments_definition; -using field_definition_start = included::field_definition_start; -using field_definition_content = included::field_definition_content; -using field_definition = included::field_definition; -using fields_definition_content = included::fields_definition_content; -using fields_definition = included::fields_definition; -using interface_type = included::interface_type; -using implements_interfaces_content = included::implements_interfaces_content; -using implements_interfaces = included::implements_interfaces; -using object_name = included::object_name; -using object_type_definition_start = included::object_type_definition_start; -using object_type_definition_object_name = included::object_type_definition_object_name; -using object_type_definition_implements_interfaces = - included::object_type_definition_implements_interfaces; -using object_type_definition_directives = included::object_type_definition_directives; -using object_type_definition_fields_definition = included::object_type_definition_fields_definition; -using object_type_definition_content = included::object_type_definition_content; -using object_type_definition = included::object_type_definition; -using interface_keyword = included::interface_keyword; -using interface_name = included::interface_name; -using interface_type_definition_start = included::interface_type_definition_start; -using interface_type_definition_interface_name = included::interface_type_definition_interface_name; -using interface_type_definition_implements_interfaces = - included::interface_type_definition_implements_interfaces; -using interface_type_definition_directives = included::interface_type_definition_directives; -using interface_type_definition_fields_definition = - included::interface_type_definition_fields_definition; -using interface_type_definition_content = included::interface_type_definition_content; -using interface_type_definition = included::interface_type_definition; -using union_keyword = included::union_keyword; -using union_name = included::union_name; -using union_type = included::union_type; -using union_member_types_start = included::union_member_types_start; -using union_member_types_content = included::union_member_types_content; -using union_member_types = included::union_member_types; -using union_type_definition_start = included::union_type_definition_start; -using union_type_definition_directives = included::union_type_definition_directives; -using union_type_definition_content = included::union_type_definition_content; -using union_type_definition = included::union_type_definition; -using enum_keyword = included::enum_keyword; -using enum_name = included::enum_name; -using enum_value_definition_start = included::enum_value_definition_start; -using enum_value_definition_content = included::enum_value_definition_content; -using enum_value_definition = included::enum_value_definition; -using enum_values_definition_start = included::enum_values_definition_start; -using enum_values_definition_content = included::enum_values_definition_content; -using enum_values_definition = included::enum_values_definition; -using enum_type_definition_start = included::enum_type_definition_start; -using enum_type_definition_name = included::enum_type_definition_name; -using enum_type_definition_directives = included::enum_type_definition_directives; -using enum_type_definition_enum_values_definition = - included::enum_type_definition_enum_values_definition; -using enum_type_definition_content = included::enum_type_definition_content; -using enum_type_definition = included::enum_type_definition; -using input_keyword = included::input_keyword; -using input_field_definition_start = included::input_field_definition_start; -using input_field_definition_type_name = included::input_field_definition_type_name; -using input_field_definition_default_value = included::input_field_definition_default_value; -using input_field_definition_directives = included::input_field_definition_directives; -using input_field_definition_content = included::input_field_definition_content; -using input_field_definition = included::input_field_definition; -using input_fields_definition_start = included::input_fields_definition_start; -using input_fields_definition_content = included::input_fields_definition_content; -using input_fields_definition = included::input_fields_definition; -using input_object_type_definition_start = included::input_object_type_definition_start; -using input_object_type_definition_object_name = included::input_object_type_definition_object_name; -using input_object_type_definition_directives = included::input_object_type_definition_directives; -using input_object_type_definition_fields_definition = - included::input_object_type_definition_fields_definition; -using input_object_type_definition_content = included::input_object_type_definition_content; -using input_object_type_definition = included::input_object_type_definition; -using type_definition = included::type_definition; -using executable_directive_location = included::executable_directive_location; -using type_system_directive_location = included::type_system_directive_location; -using directive_location = included::directive_location; -using directive_locations = included::directive_locations; -using directive_definition_start = included::directive_definition_start; -using repeatable_keyword = included::repeatable_keyword; -using directive_definition_content = included::directive_definition_content; -using directive_definition = included::directive_definition; -using type_system_definition = included::type_system_definition; -using extend_keyword = included::extend_keyword; -using operation_type_definition = included::operation_type_definition; -using schema_extension_start = included::schema_extension_start; -using schema_extension_operation_type_definitions = - included::schema_extension_operation_type_definitions; -using schema_extension_content = included::schema_extension_content; -using schema_extension = included::schema_extension; -using scalar_type_extension_start = included::scalar_type_extension_start; -using scalar_type_extension_content = included::scalar_type_extension_content; -using scalar_type_extension = included::scalar_type_extension; -using object_type_extension_start = included::object_type_extension_start; -using object_type_extension_implements_interfaces = - included::object_type_extension_implements_interfaces; -using object_type_extension_directives = included::object_type_extension_directives; -using object_type_extension_fields_definition = included::object_type_extension_fields_definition; -using object_type_extension_content = included::object_type_extension_content; -using object_type_extension = included::object_type_extension; -using interface_type_extension_start = included::interface_type_extension_start; -using interface_type_extension_implements_interfaces = - included::interface_type_extension_implements_interfaces; -using interface_type_extension_directives = included::interface_type_extension_directives; -using interface_type_extension_fields_definition = - included::interface_type_extension_fields_definition; -using interface_type_extension_content = included::interface_type_extension_content; -using interface_type_extension = included::interface_type_extension; -using union_type_extension_start = included::union_type_extension_start; -using union_type_extension_content = included::union_type_extension_content; -using union_type_extension = included::union_type_extension; -using enum_type_extension_start = included::enum_type_extension_start; -using enum_type_extension_content = included::enum_type_extension_content; -using enum_type_extension = included::enum_type_extension; -using input_object_type_extension_start = included::input_object_type_extension_start; -using input_object_type_extension_content = included::input_object_type_extension_content; -using input_object_type_extension = included::input_object_type_extension; -using type_extension = included::type_extension; -using type_system_extension = included::type_system_extension; -using mixed_definition = included::mixed_definition; -using mixed_document_content = included::mixed_document_content; -using mixed_document = included::mixed_document; -using executable_document_content = included::executable_document_content; -using executable_document = included::executable_document; -using schema_type_definition = included::schema_type_definition; -using schema_document_content = included::schema_document_content; -using schema_document = included::schema_document; +using included::alias; +using included::alias_name; +using included::argument; +using included::argument_content; +using included::argument_name; +using included::arguments; +using included::arguments_content; +using included::backslash_token; +using included::block_escape_sequence; +using included::block_quote; +using included::block_quote_character; +using included::block_quote_content; +using included::block_quote_content_lines; +using included::block_quote_empty_line; +using included::block_quote_line; +using included::block_quote_line_content; +using included::block_quote_token; +using included::bool_value; +using included::comment; +using included::default_value; +using included::default_value_content; +using included::directive; +using included::directive_content; +using included::directive_name; +using included::directives; +using included::enum_value; +using included::escaped_char; +using included::escaped_unicode; +using included::escaped_unicode_codepoint; +using included::escaped_unicode_content; +using included::exponent_indicator; +using included::exponent_part; +using included::exponent_part_content; +using included::false_keyword; +using included::field; +using included::field_arguments; +using included::field_content; +using included::field_directives; +using included::field_name; +using included::field_selection_set; +using included::field_start; +using included::float_value; +using included::fractional_part; +using included::fractional_part_content; +using included::fragment_name; +using included::fragment_spread; +using included::fragment_token; +using included::ignored; +using included::inline_fragment; +using included::input_value; +using included::input_value_content; +using included::integer_part; +using included::integer_value; +using included::list_entry; +using included::list_type; +using included::list_type_content; +using included::list_value; +using included::list_value_content; +using included::name; +using included::named_type; +using included::negative_sign; +using included::nonnull_type; +using included::nonzero_digit; +using included::null_keyword; +using included::object_field; +using included::object_field_content; +using included::object_field_name; +using included::object_value; +using included::object_value_content; +using included::on_keyword; +using included::operation_type; +using included::quote_token; +using included::sign; +using included::source_character; +using included::string_escape_sequence; +using included::string_escape_sequence_content; +using included::string_quote; +using included::string_quote_character; +using included::string_quote_content; +using included::string_value; +using included::true_keyword; +using included::type_condition; +using included::type_condition_content; +using included::type_name; +using included::type_name_content; +using included::variable; +using included::variable_content; +using included::variable_definitions; +using included::variable_definitions_content; +using included::variable_name; +using included::variable_name_content; +using included::variable_value; +using included::zero_digit; +using included::fragement_spread_or_inline_fragment_content; +using included::fragement_spread_or_inline_fragment; +using included::operation_name; +using included::selection; +using included::selection_set; +using included::selection_set_content; +using included::operation_definition_operation_type_content; +using included::arguments_definition; +using included::arguments_definition_content; +using included::arguments_definition_start; +using included::description; +using included::executable_definition; +using included::field_definition; +using included::field_definition_content; +using included::field_definition_start; +using included::fields_definition; +using included::fields_definition_content; +using included::fragment_definition; +using included::fragment_definition_content; +using included::implements_interfaces; +using included::implements_interfaces_content; +using included::interface_type; +using included::object_name; +using included::object_type_definition_object_name; +using included::object_type_definition_start; +using included::operation_definition; +using included::root_operation_definition; +using included::root_operation_definition_content; +using included::scalar_keyword; +using included::scalar_name; +using included::scalar_type_definition; +using included::scalar_type_definition_content; +using included::scalar_type_definition_start; +using included::schema_definition; +using included::schema_definition_content; +using included::schema_definition_start; +using included::schema_keyword; +using included::type_keyword; +using included::object_type_definition_implements_interfaces; +using included::interface_keyword; +using included::interface_name; +using included::interface_type_definition_interface_name; +using included::interface_type_definition_start; +using included::object_type_definition; +using included::object_type_definition_content; +using included::object_type_definition_directives; +using included::object_type_definition_fields_definition; +using included::interface_type_definition_implements_interfaces; +using included::interface_type_definition_directives; +using included::interface_type_definition_fields_definition; +using included::enum_keyword; +using included::enum_name; +using included::enum_type_definition_directives; +using included::enum_type_definition_name; +using included::enum_type_definition_start; +using included::enum_value_definition; +using included::enum_value_definition_content; +using included::enum_value_definition_start; +using included::enum_values_definition; +using included::enum_values_definition_content; +using included::enum_values_definition_start; +using included::interface_type_definition; +using included::interface_type_definition_content; +using included::union_keyword; +using included::union_member_types; +using included::union_member_types_content; +using included::union_member_types_start; +using included::union_name; +using included::union_type; +using included::union_type_definition; +using included::union_type_definition_content; +using included::union_type_definition_directives; +using included::union_type_definition_start; +using included::enum_type_definition_enum_values_definition; +using included::enum_type_definition; +using included::enum_type_definition_content; +using included::input_field_definition; +using included::input_field_definition_content; +using included::input_field_definition_default_value; +using included::input_field_definition_directives; +using included::input_field_definition_start; +using included::input_field_definition_type_name; +using included::input_fields_definition; +using included::input_fields_definition_content; +using included::input_fields_definition_start; +using included::input_keyword; +using included::input_object_type_definition_directives; +using included::input_object_type_definition_object_name; +using included::input_object_type_definition_start; +using included::input_object_type_definition_fields_definition; +using included::directive_definition; +using included::directive_definition_content; +using included::directive_definition_start; +using included::directive_location; +using included::directive_locations; +using included::executable_directive_location; +using included::extend_keyword; +using included::input_object_type_definition; +using included::input_object_type_definition_content; +using included::operation_type_definition; +using included::repeatable_keyword; +using included::schema_extension_start; +using included::type_definition; +using included::type_system_definition; +using included::type_system_directive_location; +using included::schema_extension_operation_type_definitions; +using included::object_type_extension_start; +using included::scalar_type_extension; +using included::scalar_type_extension_content; +using included::scalar_type_extension_start; +using included::schema_extension; +using included::schema_extension_content; +using included::object_type_extension_implements_interfaces; +using included::interface_type_extension_start; +using included::object_type_extension; +using included::object_type_extension_content; +using included::object_type_extension_directives; +using included::object_type_extension_fields_definition; +using included::interface_type_extension_implements_interfaces; +using included::interface_type_extension_directives; +using included::interface_type_extension_fields_definition; +using included::enum_type_extension; +using included::enum_type_extension_content; +using included::enum_type_extension_start; +using included::executable_document; +using included::executable_document_content; +using included::input_object_type_extension; +using included::input_object_type_extension_content; +using included::input_object_type_extension_start; +using included::interface_type_extension; +using included::interface_type_extension_content; +using included::mixed_definition; +using included::mixed_document; +using included::mixed_document_content; +using included::schema_document; +using included::schema_document_content; +using included::schema_type_definition; +using included::type_extension; +using included::type_system_extension; +using included::union_type_extension; +using included::union_type_extension_content; +using included::union_type_extension_start; +// clang-format on } // namespace exported diff --git a/include/graphqlservice/internal/Introspection.ixx b/include/graphqlservice/internal/Introspection.ixx index 4bb0d634..f46c54c6 100644 --- a/include/graphqlservice/internal/Introspection.ixx +++ b/include/graphqlservice/internal/Introspection.ixx @@ -13,12 +13,14 @@ export namespace graphql::introspection { namespace exported { -using Schema = included::Schema; -using Type = included::Type; -using Field = included::Field; -using InputValue = included::InputValue; -using EnumValue = included::EnumValue; -using Directive = included::Directive; +// clang-format off +using included::Schema; +using included::Type; +using included::Field; +using included::InputValue; +using included::EnumValue; +using included::Directive; +// clang-format on } // namespace exported diff --git a/include/graphqlservice/internal/Schema.ixx b/include/graphqlservice/internal/Schema.ixx index d52f8880..fd058694 100644 --- a/include/graphqlservice/internal/Schema.ixx +++ b/include/graphqlservice/internal/Schema.ixx @@ -20,8 +20,10 @@ namespace introspection { namespace exported { -using TypeKind = included::introspection::TypeKind; -using DirectiveLocation = included::introspection::DirectiveLocation; +// clang-format off +using included::introspection::TypeKind; +using included::introspection::DirectiveLocation; +// clang-format on } // namespace exported @@ -33,20 +35,22 @@ namespace schema { namespace exported { -using Schema = included::schema::Schema; -using BaseType = included::schema::BaseType; -using ScalarType = included::schema::ScalarType; -using ObjectType = included::schema::ObjectType; -using InterfaceType = included::schema::InterfaceType; -using UnionType = included::schema::UnionType; -using EnumValueType = included::schema::EnumValueType; -using EnumType = included::schema::EnumType; -using InputObjectType = included::schema::InputObjectType; -using WrapperType = included::schema::WrapperType; -using Field = included::schema::Field; -using InputValue = included::schema::InputValue; -using EnumValue = included::schema::EnumValue; -using Directive = included::schema::Directive; +// clang-format off +using included::schema::Schema; +using included::schema::BaseType; +using included::schema::ScalarType; +using included::schema::ObjectType; +using included::schema::InterfaceType; +using included::schema::UnionType; +using included::schema::EnumValueType; +using included::schema::EnumType; +using included::schema::InputObjectType; +using included::schema::WrapperType; +using included::schema::Field; +using included::schema::InputValue; +using included::schema::EnumValue; +using included::schema::Directive; +// clang-format on } // namespace exported diff --git a/include/graphqlservice/internal/SortedMap.ixx b/include/graphqlservice/internal/SortedMap.ixx index d0719481..18415848 100644 --- a/include/graphqlservice/internal/SortedMap.ixx +++ b/include/graphqlservice/internal/SortedMap.ixx @@ -13,36 +13,16 @@ export namespace graphql::internal { namespace exported { -template -using sorted_map_key = included::sorted_map_key; - -template ()->second)> -[[nodiscard("unnecessary call")]] constexpr std::pair sorted_map_equal_range( - Iterator itrBegin, Iterator itrEnd, K&& key) noexcept -{ - return included::sorted_map_equal_range(itrBegin, itrEnd, std::forward(key)); -} - -template -[[nodiscard("unnecessary call")]] constexpr auto sorted_map_lookup( - const Container& container, K&& key) noexcept -{ - return included::sorted_map_lookup(container, std::forward(key)); -} - -template > -using sorted_map = included::sorted_map; - -template > -using sorted_set = included::sorted_set; - -using shorter_or_less = included::shorter_or_less; - -template -using string_view_map = included::string_view_map; - -using string_view_set = included::string_view_set; +// clang-format off +using included::sorted_map_key; +using included::sorted_map_equal_range; +using included::sorted_map_lookup; +using included::sorted_map; +using included::sorted_set; +using included::shorter_or_less; +using included::string_view_map; +using included::string_view_set; +// clang-format on } // namespace exported diff --git a/include/graphqlservice/internal/SyntaxTree.ixx b/include/graphqlservice/internal/SyntaxTree.ixx index 89127a32..67c3134b 100644 --- a/include/graphqlservice/internal/SyntaxTree.ixx +++ b/include/graphqlservice/internal/SyntaxTree.ixx @@ -11,10 +11,12 @@ export namespace graphql::peg { namespace exported { +// clang-format off using namespace tao::graphqlpeg; namespace peginternal = tao::graphqlpeg::internal; -using ast_node = graphql::peg::ast_node; +using graphql::peg::ast_node; +// clang-format on } // namespace exported diff --git a/include/graphqlservice/introspection/DirectiveObject.ixx b/include/graphqlservice/introspection/DirectiveObject.ixx index 3074c61c..97f3dae7 100644 --- a/include/graphqlservice/introspection/DirectiveObject.ixx +++ b/include/graphqlservice/introspection/DirectiveObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using Directive = included::Directive; +using included::Directive; } // namespace exported diff --git a/include/graphqlservice/introspection/EnumValueObject.ixx b/include/graphqlservice/introspection/EnumValueObject.ixx index 3fe1aac9..572acd70 100644 --- a/include/graphqlservice/introspection/EnumValueObject.ixx +++ b/include/graphqlservice/introspection/EnumValueObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using EnumValue = included::EnumValue; +using included::EnumValue; } // namespace exported diff --git a/include/graphqlservice/introspection/FieldObject.ixx b/include/graphqlservice/introspection/FieldObject.ixx index 6458133e..b98ed284 100644 --- a/include/graphqlservice/introspection/FieldObject.ixx +++ b/include/graphqlservice/introspection/FieldObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using Field = included::Field; +using included::Field; } // namespace exported diff --git a/include/graphqlservice/introspection/InputValueObject.ixx b/include/graphqlservice/introspection/InputValueObject.ixx index ffa0ce4e..b3ca2cfd 100644 --- a/include/graphqlservice/introspection/InputValueObject.ixx +++ b/include/graphqlservice/introspection/InputValueObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using InputValue = included::InputValue; +using included::InputValue; } // namespace exported diff --git a/include/graphqlservice/introspection/IntrospectionSchema.ixx b/include/graphqlservice/introspection/IntrospectionSchema.ixx index 859747cb..77d96507 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.ixx +++ b/include/graphqlservice/introspection/IntrospectionSchema.ixx @@ -15,64 +15,22 @@ export namespace graphql::introspection { namespace exported { -using TypeKind = included::TypeKind; - -constexpr auto getTypeKindNames() noexcept -{ - return included::getTypeKindNames(); -} - -constexpr auto getTypeKindValues() noexcept -{ - return included::getTypeKindValues(); -} - -using DirectiveLocation = included::DirectiveLocation; - -constexpr auto getDirectiveLocationNames() noexcept -{ - return included::getDirectiveLocationNames(); -} - -constexpr auto getDirectiveLocationValues() noexcept -{ - return included::getDirectiveLocationValues(); -} - -void AddSchemaDetails(const std::shared_ptr& typeSchema, const std::shared_ptr& schema) -{ - included::AddSchemaDetails(typeSchema, schema); -} - -void AddTypeDetails(const std::shared_ptr& typeType, const std::shared_ptr& schema) -{ - included::AddTypeDetails(typeType, schema); -} - -void AddFieldDetails(const std::shared_ptr& typeField, const std::shared_ptr& schema) -{ - included::AddFieldDetails(typeField, schema); -} - -void AddInputValueDetails(const std::shared_ptr& typeInputValue, const std::shared_ptr& schema) -{ - included::AddInputValueDetails(typeInputValue, schema); -} - -void AddEnumValueDetails(const std::shared_ptr& typeEnumValue, const std::shared_ptr& schema) -{ - included::AddEnumValueDetails(typeEnumValue, schema); -} - -void AddDirectiveDetails(const std::shared_ptr& typeDirective, const std::shared_ptr& schema) -{ - included::AddDirectiveDetails(typeDirective, schema); -} - -void AddTypesToSchema(const std::shared_ptr& schema) -{ - included::AddTypesToSchema(schema); -} +using included::TypeKind; +using included::getTypeKindNames; +using included::getTypeKindValues; + +using included::DirectiveLocation; +using included::getDirectiveLocationNames; +using included::getDirectiveLocationValues; + +using included::AddSchemaDetails; +using included::AddTypeDetails; +using included::AddFieldDetails; +using included::AddInputValueDetails; +using included::AddEnumValueDetails; +using included::AddDirectiveDetails; + +using included::AddTypesToSchema; } // namespace exported diff --git a/include/graphqlservice/introspection/SchemaObject.ixx b/include/graphqlservice/introspection/SchemaObject.ixx index b96287b2..063cc3f7 100644 --- a/include/graphqlservice/introspection/SchemaObject.ixx +++ b/include/graphqlservice/introspection/SchemaObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using Schema = included::Schema; +using included::Schema; } // namespace exported diff --git a/include/graphqlservice/introspection/TypeObject.ixx b/include/graphqlservice/introspection/TypeObject.ixx index 1c16e7a1..401a9329 100644 --- a/include/graphqlservice/introspection/TypeObject.ixx +++ b/include/graphqlservice/introspection/TypeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using Type = included::Type; +using included::Type; } // namespace exported diff --git a/samples/client/benchmark/BenchmarkClient.ixx b/samples/client/benchmark/BenchmarkClient.ixx index eb7d9ea0..ab820a60 100644 --- a/samples/client/benchmark/BenchmarkClient.ixx +++ b/samples/client/benchmark/BenchmarkClient.ixx @@ -15,9 +15,23 @@ export namespace graphql::client { namespace exported { +namespace benchmark { + +using included::benchmark::GetRequestText; +using included::benchmark::GetRequestObject; + +} // namespace benchmark + namespace query::Query { -using Traits = included::query::Query::Traits; +using included::benchmark::GetRequestText; +using included::benchmark::GetRequestObject; +using included::query::Query::GetOperationName; + +using included::query::Query::Response; +using included::query::Query::parseResponse; + +using included::query::Query::Traits; } // namespace query::Query diff --git a/samples/client/multiple/MultipleQueriesClient.ixx b/samples/client/multiple/MultipleQueriesClient.ixx index 074fbd7f..b4ea36cf 100644 --- a/samples/client/multiple/MultipleQueriesClient.ixx +++ b/samples/client/multiple/MultipleQueriesClient.ixx @@ -17,39 +17,86 @@ namespace exported { namespace multiple { -using TaskState = included::multiple::TaskState; +using included::multiple::GetRequestText; +using included::multiple::GetRequestObject; -using CompleteTaskInput = included::multiple::CompleteTaskInput; +using included::multiple::TaskState; + +using included::multiple::CompleteTaskInput; } // namespace multiple namespace query::Appointments { -using Traits = included::query::Appointments::Traits; +using included::multiple::GetRequestText; +using included::multiple::GetRequestObject; +using included::query::Appointments::GetOperationName; + +using included::query::Appointments::Response; +using included::query::Appointments::parseResponse; + +using included::query::Appointments::Traits; } // namespace query::Appointments namespace query::Tasks { -using Traits = included::query::Tasks::Traits; +using included::multiple::GetRequestText; +using included::multiple::GetRequestObject; +using included::query::Tasks::GetOperationName; + +using included::query::Tasks::Response; +using included::query::Tasks::parseResponse; + +using included::query::Tasks::Traits; } // namespace query::Tasks namespace query::UnreadCounts { -using Traits = included::query::UnreadCounts::Traits; +using included::multiple::GetRequestText; +using included::multiple::GetRequestObject; +using included::query::UnreadCounts::GetOperationName; + +using included::query::UnreadCounts::Response; +using included::query::UnreadCounts::parseResponse; + +using included::query::UnreadCounts::Traits; } // namespace query::UnreadCounts namespace query::Miscellaneous { -using Traits = included::query::Miscellaneous::Traits; +using included::multiple::GetRequestText; +using included::multiple::GetRequestObject; +using included::query::Miscellaneous::GetOperationName; + +using included::multiple::TaskState; + +using included::query::Miscellaneous::Response; +using included::query::Miscellaneous::parseResponse; + +using included::query::Miscellaneous::Traits; } // namespace query::Miscellaneous namespace mutation::CompleteTaskMutation { -using Traits = included::mutation::CompleteTaskMutation::Traits; +using included::multiple::GetRequestText; +using included::multiple::GetRequestObject; +using included::mutation::CompleteTaskMutation::GetOperationName; + +using included::multiple::TaskState; + +using included::multiple::CompleteTaskInput; + +using included::mutation::CompleteTaskMutation::Variables; +using included::mutation::CompleteTaskMutation::serializeVariables; + +using included::mutation::CompleteTaskMutation::Response; +using included::mutation::CompleteTaskMutation::parseResponse; + +using included::mutation::CompleteTaskMutation::Traits; } // namespace mutation::CompleteTaskMutation diff --git a/samples/client/mutate/MutateClient.ixx b/samples/client/mutate/MutateClient.ixx index 4ffa4c81..fe9c9592 100644 --- a/samples/client/mutate/MutateClient.ixx +++ b/samples/client/mutate/MutateClient.ixx @@ -17,15 +17,32 @@ namespace exported { namespace mutate { -using TaskState = included::mutate::TaskState; +using included::mutate::GetRequestText; +using included::mutate::GetRequestObject; -using CompleteTaskInput = included::mutate::CompleteTaskInput; +using included::mutate::TaskState; + +using included::mutate::CompleteTaskInput; } // namespace mutate namespace mutation::CompleteTaskMutation { -using Traits = included::mutation::CompleteTaskMutation::Traits; +using included::mutate::GetRequestText; +using included::mutate::GetRequestObject; +using included::mutation::CompleteTaskMutation::GetOperationName; + +using included::mutate::TaskState; + +using included::mutate::CompleteTaskInput; + +using included::mutation::CompleteTaskMutation::Variables; +using included::mutation::CompleteTaskMutation::serializeVariables; + +using included::mutation::CompleteTaskMutation::Response; +using included::mutation::CompleteTaskMutation::parseResponse; + +using included::mutation::CompleteTaskMutation::Traits; } // namespace mutation::CompleteTaskMutation diff --git a/samples/client/nestedinput/NestedInputClient.ixx b/samples/client/nestedinput/NestedInputClient.ixx index 197b8ea2..b64a60b6 100644 --- a/samples/client/nestedinput/NestedInputClient.ixx +++ b/samples/client/nestedinput/NestedInputClient.ixx @@ -15,14 +15,36 @@ export namespace graphql::client { namespace exported { -using InputA = included::nestedinput::InputA; -using InputB = included::nestedinput::InputB; -using InputABCD = included::nestedinput::InputABCD; -using InputBC = included::nestedinput::InputBC; +namespace nestedinput { + +using included::nestedinput::GetRequestText; +using included::nestedinput::GetRequestObject; + +using included::nestedinput::InputA; +using included::nestedinput::InputB; +using included::nestedinput::InputABCD; +using included::nestedinput::InputBC; + +} // namespace nestedinput namespace query::testQuery { -using Traits = included::query::testQuery::Traits; +using included::nestedinput::GetRequestText; +using included::nestedinput::GetRequestObject; +using included::query::testQuery::GetOperationName; + +using included::nestedinput::InputA; +using included::nestedinput::InputB; +using included::nestedinput::InputABCD; +using included::nestedinput::InputBC; + +using included::query::testQuery::Variables; +using included::query::testQuery::serializeVariables; + +using included::query::testQuery::Response; +using included::query::testQuery::parseResponse; + +using included::query::testQuery::Traits; } // namespace query::testQuery diff --git a/samples/client/query/QueryClient.ixx b/samples/client/query/QueryClient.ixx index 660a2afd..f765e94a 100644 --- a/samples/client/query/QueryClient.ixx +++ b/samples/client/query/QueryClient.ixx @@ -17,13 +17,25 @@ namespace exported { namespace query { -using TaskState = included::query::TaskState; +using included::query::GetRequestText; +using included::query::GetRequestObject; + +using included::query::TaskState; } // namespace query namespace query::Query { -using Traits = included::query::Query::Traits; +using included::query::GetRequestText; +using included::query::GetRequestObject; +using included::query::Query::GetOperationName; + +using included::query::TaskState; + +using included::query::Query::Response; +using included::query::Query::parseResponse; + +using included::query::Query::Traits; } // namespace query::Query diff --git a/samples/client/subscribe/SubscribeClient.ixx b/samples/client/subscribe/SubscribeClient.ixx index 3cba1362..aeadc3a3 100644 --- a/samples/client/subscribe/SubscribeClient.ixx +++ b/samples/client/subscribe/SubscribeClient.ixx @@ -15,9 +15,23 @@ export namespace graphql::client { namespace exported { +namespace subscribe { + +using included::subscribe::GetRequestText; +using included::subscribe::GetRequestObject; + +} // namespace subscribe + namespace subscription::TestSubscription { -using Traits = included::subscription::TestSubscription::Traits; +using included::subscribe::GetRequestText; +using included::subscribe::GetRequestObject; +using included::subscription::TestSubscription::GetOperationName; + +using included::subscription::TestSubscription::Response; +using included::subscription::TestSubscription::parseResponse; + +using included::subscription::TestSubscription::Traits; } // namespace subscription::TestSubscription diff --git a/samples/learn/schema/CharacterObject.ixx b/samples/learn/schema/CharacterObject.ixx index d1803df5..eb23c6f2 100644 --- a/samples/learn/schema/CharacterObject.ixx +++ b/samples/learn/schema/CharacterObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::learn::object { namespace exported { -using Character = included::Character; +using included::Character; } // namespace exported diff --git a/samples/learn/schema/DroidObject.ixx b/samples/learn/schema/DroidObject.ixx index 617a0b0d..795b4232 100644 --- a/samples/learn/schema/DroidObject.ixx +++ b/samples/learn/schema/DroidObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::learn::object { namespace exported { -using Droid = included::Droid; +using included::Droid; } // namespace exported diff --git a/samples/learn/schema/HumanObject.ixx b/samples/learn/schema/HumanObject.ixx index 5460899c..07db6b5b 100644 --- a/samples/learn/schema/HumanObject.ixx +++ b/samples/learn/schema/HumanObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::learn::object { namespace exported { -using Human = included::Human; +using included::Human; } // namespace exported diff --git a/samples/learn/schema/MutationObject.ixx b/samples/learn/schema/MutationObject.ixx index d31584be..4e233adf 100644 --- a/samples/learn/schema/MutationObject.ixx +++ b/samples/learn/schema/MutationObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::learn::object { namespace exported { -using Mutation = included::Mutation; +using included::Mutation; } // namespace exported diff --git a/samples/learn/schema/QueryObject.ixx b/samples/learn/schema/QueryObject.ixx index 55b289db..de1e3865 100644 --- a/samples/learn/schema/QueryObject.ixx +++ b/samples/learn/schema/QueryObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::learn::object { namespace exported { -using Query = included::Query; +using included::Query; } // namespace exported diff --git a/samples/learn/schema/ReviewObject.ixx b/samples/learn/schema/ReviewObject.ixx index a31c333d..492a843f 100644 --- a/samples/learn/schema/ReviewObject.ixx +++ b/samples/learn/schema/ReviewObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::learn::object { namespace exported { -using Review = included::Review; +using included::Review; } // namespace exported diff --git a/samples/learn/schema/StarWarsSchema.ixx b/samples/learn/schema/StarWarsSchema.ixx index be2a0853..b0a8eb89 100644 --- a/samples/learn/schema/StarWarsSchema.ixx +++ b/samples/learn/schema/StarWarsSchema.ixx @@ -15,56 +15,22 @@ export namespace graphql::learn { namespace exported { -using Episode = included::Episode; +using included::Episode; +using included::getEpisodeNames; +using included::getEpisodeValues; -constexpr auto getEpisodeNames() noexcept -{ - return included::getEpisodeNames(); -} +using included::ReviewInput; -constexpr auto getEpisodeValues() noexcept -{ - return included::getEpisodeValues(); -} +using included::Operations; -using ReviewInput= included::ReviewInput; +using included::AddCharacterDetails; +using included::AddHumanDetails; +using included::AddDroidDetails; +using included::AddQueryDetails; +using included::AddReviewDetails; +using included::AddMutationDetails; -using Operations = included::Operations; - -void AddCharacterDetails(const std::shared_ptr& typeCharacter, const std::shared_ptr& schema) -{ - included::AddCharacterDetails(typeCharacter, schema); -} - -void AddHumanDetails(const std::shared_ptr& typeHuman, const std::shared_ptr& schema) -{ - included::AddHumanDetails(typeHuman, schema); -} - -void AddDroidDetails(const std::shared_ptr& typeDroid, const std::shared_ptr& schema) -{ - included::AddDroidDetails(typeDroid, schema); -} - -void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) -{ - included::AddQueryDetails(typeQuery, schema); -} - -void AddReviewDetails(const std::shared_ptr& typeReview, const std::shared_ptr& schema) -{ - included::AddReviewDetails(typeReview, schema); -} - -void AddMutationDetails(const std::shared_ptr& typeMutation, const std::shared_ptr& schema) -{ - included::AddMutationDetails(typeMutation, schema); -} - -std::shared_ptr GetSchema() -{ - return included::GetSchema(); -} +using included::GetSchema; } // namespace exported diff --git a/samples/proxy/query/ProxyClient.ixx b/samples/proxy/query/ProxyClient.ixx index 4593cade..39f8167a 100644 --- a/samples/proxy/query/ProxyClient.ixx +++ b/samples/proxy/query/ProxyClient.ixx @@ -15,9 +15,26 @@ export namespace graphql::client { namespace exported { +namespace proxy { + +using included::proxy::GetRequestText; +using included::proxy::GetRequestObject; + +} // namespace proxy + namespace query::relayQuery { -using Traits = included::query::relayQuery::Traits; +using included::proxy::GetRequestText; +using included::proxy::GetRequestObject; +using included::query::relayQuery::GetOperationName; + +using included::query::relayQuery::Variables; +using included::query::relayQuery::serializeVariables; + +using included::query::relayQuery::Response; +using included::query::relayQuery::parseResponse; + +using included::query::relayQuery::Traits; } // namespace query::relayQuery diff --git a/samples/proxy/schema/ProxySchema.ixx b/samples/proxy/schema/ProxySchema.ixx index 6a6166bd..98a36d37 100644 --- a/samples/proxy/schema/ProxySchema.ixx +++ b/samples/proxy/schema/ProxySchema.ixx @@ -15,17 +15,11 @@ export namespace graphql::proxy { namespace exported { -using Operations = included::Operations; +using included::Operations; -void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) -{ - included::AddQueryDetails(typeQuery, schema); -} +using included::AddQueryDetails; -std::shared_ptr GetSchema() -{ - return included::GetSchema(); -} +using included::GetSchema; } // namespace exported diff --git a/samples/proxy/schema/QueryObject.ixx b/samples/proxy/schema/QueryObject.ixx index 55a7a1ca..daa0f013 100644 --- a/samples/proxy/schema/QueryObject.ixx +++ b/samples/proxy/schema/QueryObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::proxy::object { namespace exported { -using Query = included::Query; +using included::Query; } // namespace exported diff --git a/samples/today/nointrospection/AppointmentConnectionObject.ixx b/samples/today/nointrospection/AppointmentConnectionObject.ixx index 43f105e3..b9a9f601 100644 --- a/samples/today/nointrospection/AppointmentConnectionObject.ixx +++ b/samples/today/nointrospection/AppointmentConnectionObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using AppointmentConnection = included::AppointmentConnection; +using included::AppointmentConnection; } // namespace exported diff --git a/samples/today/nointrospection/AppointmentEdgeObject.ixx b/samples/today/nointrospection/AppointmentEdgeObject.ixx index f90e04aa..2c4e5e77 100644 --- a/samples/today/nointrospection/AppointmentEdgeObject.ixx +++ b/samples/today/nointrospection/AppointmentEdgeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using AppointmentEdge = included::AppointmentEdge; +using included::AppointmentEdge; } // namespace exported diff --git a/samples/today/nointrospection/AppointmentObject.ixx b/samples/today/nointrospection/AppointmentObject.ixx index 5d166480..4f3a78b2 100644 --- a/samples/today/nointrospection/AppointmentObject.ixx +++ b/samples/today/nointrospection/AppointmentObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Appointment = included::Appointment; +using included::Appointment; } // namespace exported diff --git a/samples/today/nointrospection/CompleteTaskPayloadObject.ixx b/samples/today/nointrospection/CompleteTaskPayloadObject.ixx index 57fadd1a..645bb2a8 100644 --- a/samples/today/nointrospection/CompleteTaskPayloadObject.ixx +++ b/samples/today/nointrospection/CompleteTaskPayloadObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using CompleteTaskPayload = included::CompleteTaskPayload; +using included::CompleteTaskPayload; } // namespace exported diff --git a/samples/today/nointrospection/ExpensiveObject.ixx b/samples/today/nointrospection/ExpensiveObject.ixx index d0d0f9cf..ff03e488 100644 --- a/samples/today/nointrospection/ExpensiveObject.ixx +++ b/samples/today/nointrospection/ExpensiveObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Expensive = included::Expensive; +using included::Expensive; } // namespace exported diff --git a/samples/today/nointrospection/FolderConnectionObject.ixx b/samples/today/nointrospection/FolderConnectionObject.ixx index 82c8fad0..9ad8b9b6 100644 --- a/samples/today/nointrospection/FolderConnectionObject.ixx +++ b/samples/today/nointrospection/FolderConnectionObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using FolderConnection = included::FolderConnection; +using included::FolderConnection; } // namespace exported diff --git a/samples/today/nointrospection/FolderEdgeObject.ixx b/samples/today/nointrospection/FolderEdgeObject.ixx index 28317740..6dd06a63 100644 --- a/samples/today/nointrospection/FolderEdgeObject.ixx +++ b/samples/today/nointrospection/FolderEdgeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using FolderEdge = included::FolderEdge; +using included::FolderEdge; } // namespace exported diff --git a/samples/today/nointrospection/FolderObject.ixx b/samples/today/nointrospection/FolderObject.ixx index c8b36149..f4bf4e11 100644 --- a/samples/today/nointrospection/FolderObject.ixx +++ b/samples/today/nointrospection/FolderObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Folder = included::Folder; +using included::Folder; } // namespace exported diff --git a/samples/today/nointrospection/MutationObject.ixx b/samples/today/nointrospection/MutationObject.ixx index 5a2fd5ed..80008cd9 100644 --- a/samples/today/nointrospection/MutationObject.ixx +++ b/samples/today/nointrospection/MutationObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Mutation = included::Mutation; +using included::Mutation; } // namespace exported diff --git a/samples/today/nointrospection/NestedTypeObject.ixx b/samples/today/nointrospection/NestedTypeObject.ixx index 095cdf82..7895972c 100644 --- a/samples/today/nointrospection/NestedTypeObject.ixx +++ b/samples/today/nointrospection/NestedTypeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using NestedType = included::NestedType; +using included::NestedType; } // namespace exported diff --git a/samples/today/nointrospection/NodeObject.ixx b/samples/today/nointrospection/NodeObject.ixx index 558df3ef..eafee7d1 100644 --- a/samples/today/nointrospection/NodeObject.ixx +++ b/samples/today/nointrospection/NodeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Node = included::Node; +using included::Node; } // namespace exported diff --git a/samples/today/nointrospection/PageInfoObject.ixx b/samples/today/nointrospection/PageInfoObject.ixx index 7ef13425..f68e2225 100644 --- a/samples/today/nointrospection/PageInfoObject.ixx +++ b/samples/today/nointrospection/PageInfoObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using PageInfo = included::PageInfo; +using included::PageInfo; } // namespace exported diff --git a/samples/today/nointrospection/QueryObject.ixx b/samples/today/nointrospection/QueryObject.ixx index 8a2b3938..5388c782 100644 --- a/samples/today/nointrospection/QueryObject.ixx +++ b/samples/today/nointrospection/QueryObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Query = included::Query; +using included::Query; } // namespace exported diff --git a/samples/today/nointrospection/SubscriptionObject.ixx b/samples/today/nointrospection/SubscriptionObject.ixx index 3c359438..dd90d666 100644 --- a/samples/today/nointrospection/SubscriptionObject.ixx +++ b/samples/today/nointrospection/SubscriptionObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Subscription = included::Subscription; +using included::Subscription; } // namespace exported diff --git a/samples/today/nointrospection/TaskConnectionObject.ixx b/samples/today/nointrospection/TaskConnectionObject.ixx index 57c8c868..1767efeb 100644 --- a/samples/today/nointrospection/TaskConnectionObject.ixx +++ b/samples/today/nointrospection/TaskConnectionObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using TaskConnection = included::TaskConnection; +using included::TaskConnection; } // namespace exported diff --git a/samples/today/nointrospection/TaskEdgeObject.ixx b/samples/today/nointrospection/TaskEdgeObject.ixx index 52d7a41f..61d2bd63 100644 --- a/samples/today/nointrospection/TaskEdgeObject.ixx +++ b/samples/today/nointrospection/TaskEdgeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using TaskEdge = included::TaskEdge; +using included::TaskEdge; } // namespace exported diff --git a/samples/today/nointrospection/TaskObject.ixx b/samples/today/nointrospection/TaskObject.ixx index a6d15c00..8a3b6e0a 100644 --- a/samples/today/nointrospection/TaskObject.ixx +++ b/samples/today/nointrospection/TaskObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Task = included::Task; +using included::Task; } // namespace exported diff --git a/samples/today/nointrospection/TodaySchema.ixx b/samples/today/nointrospection/TodaySchema.ixx index 1cce90c6..7c1f5d30 100644 --- a/samples/today/nointrospection/TodaySchema.ixx +++ b/samples/today/nointrospection/TodaySchema.ixx @@ -15,124 +15,42 @@ export namespace graphql::today { namespace exported { -using TaskState = included::TaskState; - -constexpr auto getTaskStateNames() noexcept -{ - return included::getTaskStateNames(); -} - -constexpr auto getTaskStateValues() noexcept -{ - return included::getTaskStateValues(); -} - -using CompleteTaskInput= included::CompleteTaskInput; -using ThirdNestedInput= included::ThirdNestedInput; -using FourthNestedInput= included::FourthNestedInput; -using IncludeNullableSelfInput= included::IncludeNullableSelfInput; -using IncludeNonNullableListSelfInput= included::IncludeNonNullableListSelfInput; -using StringOperationFilterInput= included::StringOperationFilterInput; -using SecondNestedInput= included::SecondNestedInput; -using ForwardDeclaredInput= included::ForwardDeclaredInput; -using FirstNestedInput= included::FirstNestedInput; - -using Operations = included::Operations; - -void AddNodeDetails(const std::shared_ptr& typeNode, const std::shared_ptr& schema) -{ - included::AddNodeDetails(typeNode, schema); -} - -void AddUnionTypeDetails(const std::shared_ptr& typeUnionType, const std::shared_ptr& schema) -{ - included::AddUnionTypeDetails(typeUnionType, schema); -} - -void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) -{ - included::AddQueryDetails(typeQuery, schema); -} - -void AddPageInfoDetails(const std::shared_ptr& typePageInfo, const std::shared_ptr& schema) -{ - included::AddPageInfoDetails(typePageInfo, schema); -} - -void AddAppointmentEdgeDetails(const std::shared_ptr& typeAppointmentEdge, const std::shared_ptr& schema) -{ - included::AddAppointmentEdgeDetails(typeAppointmentEdge, schema); -} - -void AddAppointmentConnectionDetails(const std::shared_ptr& typeAppointmentConnection, const std::shared_ptr& schema) -{ - included::AddAppointmentConnectionDetails(typeAppointmentConnection, schema); -} - -void AddTaskEdgeDetails(const std::shared_ptr& typeTaskEdge, const std::shared_ptr& schema) -{ - included::AddTaskEdgeDetails(typeTaskEdge, schema); -} - -void AddTaskConnectionDetails(const std::shared_ptr& typeTaskConnection, const std::shared_ptr& schema) -{ - included::AddTaskConnectionDetails(typeTaskConnection, schema); -} - -void AddFolderEdgeDetails(const std::shared_ptr& typeFolderEdge, const std::shared_ptr& schema) -{ - included::AddFolderEdgeDetails(typeFolderEdge, schema); -} - -void AddFolderConnectionDetails(const std::shared_ptr& typeFolderConnection, const std::shared_ptr& schema) -{ - included::AddFolderConnectionDetails(typeFolderConnection, schema); -} - -void AddCompleteTaskPayloadDetails(const std::shared_ptr& typeCompleteTaskPayload, const std::shared_ptr& schema) -{ - included::AddCompleteTaskPayloadDetails(typeCompleteTaskPayload, schema); -} - -void AddMutationDetails(const std::shared_ptr& typeMutation, const std::shared_ptr& schema) -{ - included::AddMutationDetails(typeMutation, schema); -} - -void AddSubscriptionDetails(const std::shared_ptr& typeSubscription, const std::shared_ptr& schema) -{ - included::AddSubscriptionDetails(typeSubscription, schema); -} - -void AddAppointmentDetails(const std::shared_ptr& typeAppointment, const std::shared_ptr& schema) -{ - included::AddAppointmentDetails(typeAppointment, schema); -} - -void AddTaskDetails(const std::shared_ptr& typeTask, const std::shared_ptr& schema) -{ - included::AddTaskDetails(typeTask, schema); -} - -void AddFolderDetails(const std::shared_ptr& typeFolder, const std::shared_ptr& schema) -{ - included::AddFolderDetails(typeFolder, schema); -} - -void AddNestedTypeDetails(const std::shared_ptr& typeNestedType, const std::shared_ptr& schema) -{ - included::AddNestedTypeDetails(typeNestedType, schema); -} - -void AddExpensiveDetails(const std::shared_ptr& typeExpensive, const std::shared_ptr& schema) -{ - included::AddExpensiveDetails(typeExpensive, schema); -} - -std::shared_ptr GetSchema() -{ - return included::GetSchema(); -} +using included::TaskState; +using included::getTaskStateNames; +using included::getTaskStateValues; + +using included::CompleteTaskInput; +using included::ThirdNestedInput; +using included::FourthNestedInput; +using included::IncludeNullableSelfInput; +using included::IncludeNonNullableListSelfInput; +using included::StringOperationFilterInput; +using included::SecondNestedInput; +using included::ForwardDeclaredInput; +using included::FirstNestedInput; + +using included::Operations; + +using included::AddNodeDetails; +using included::AddUnionTypeDetails; +using included::AddQueryDetails; +using included::AddPageInfoDetails; +using included::AddAppointmentEdgeDetails; +using included::AddAppointmentConnectionDetails; +using included::AddTaskEdgeDetails; +using included::AddTaskConnectionDetails; +using included::AddFolderEdgeDetails; +using included::AddFolderConnectionDetails; +using included::AddCompleteTaskPayloadDetails; +using included::AddMutationDetails; +using included::AddSubscriptionDetails; +using included::AddAppointmentDetails; +using included::AddTaskDetails; +using included::AddFolderDetails; +using included::AddNestedTypeDetails; +using included::AddExpensiveDetails; + +using included::GetSchema; } // namespace exported diff --git a/samples/today/nointrospection/UnionTypeObject.ixx b/samples/today/nointrospection/UnionTypeObject.ixx index dfca5cc6..362b8a41 100644 --- a/samples/today/nointrospection/UnionTypeObject.ixx +++ b/samples/today/nointrospection/UnionTypeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using UnionType = included::UnionType; +using included::UnionType; } // namespace exported diff --git a/samples/today/schema/AppointmentConnectionObject.ixx b/samples/today/schema/AppointmentConnectionObject.ixx index 43f105e3..b9a9f601 100644 --- a/samples/today/schema/AppointmentConnectionObject.ixx +++ b/samples/today/schema/AppointmentConnectionObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using AppointmentConnection = included::AppointmentConnection; +using included::AppointmentConnection; } // namespace exported diff --git a/samples/today/schema/AppointmentEdgeObject.ixx b/samples/today/schema/AppointmentEdgeObject.ixx index f90e04aa..2c4e5e77 100644 --- a/samples/today/schema/AppointmentEdgeObject.ixx +++ b/samples/today/schema/AppointmentEdgeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using AppointmentEdge = included::AppointmentEdge; +using included::AppointmentEdge; } // namespace exported diff --git a/samples/today/schema/AppointmentObject.ixx b/samples/today/schema/AppointmentObject.ixx index 5d166480..4f3a78b2 100644 --- a/samples/today/schema/AppointmentObject.ixx +++ b/samples/today/schema/AppointmentObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Appointment = included::Appointment; +using included::Appointment; } // namespace exported diff --git a/samples/today/schema/CompleteTaskPayloadObject.ixx b/samples/today/schema/CompleteTaskPayloadObject.ixx index 57fadd1a..645bb2a8 100644 --- a/samples/today/schema/CompleteTaskPayloadObject.ixx +++ b/samples/today/schema/CompleteTaskPayloadObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using CompleteTaskPayload = included::CompleteTaskPayload; +using included::CompleteTaskPayload; } // namespace exported diff --git a/samples/today/schema/ExpensiveObject.ixx b/samples/today/schema/ExpensiveObject.ixx index d0d0f9cf..ff03e488 100644 --- a/samples/today/schema/ExpensiveObject.ixx +++ b/samples/today/schema/ExpensiveObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Expensive = included::Expensive; +using included::Expensive; } // namespace exported diff --git a/samples/today/schema/FolderConnectionObject.ixx b/samples/today/schema/FolderConnectionObject.ixx index 82c8fad0..9ad8b9b6 100644 --- a/samples/today/schema/FolderConnectionObject.ixx +++ b/samples/today/schema/FolderConnectionObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using FolderConnection = included::FolderConnection; +using included::FolderConnection; } // namespace exported diff --git a/samples/today/schema/FolderEdgeObject.ixx b/samples/today/schema/FolderEdgeObject.ixx index 28317740..6dd06a63 100644 --- a/samples/today/schema/FolderEdgeObject.ixx +++ b/samples/today/schema/FolderEdgeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using FolderEdge = included::FolderEdge; +using included::FolderEdge; } // namespace exported diff --git a/samples/today/schema/FolderObject.ixx b/samples/today/schema/FolderObject.ixx index c8b36149..f4bf4e11 100644 --- a/samples/today/schema/FolderObject.ixx +++ b/samples/today/schema/FolderObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Folder = included::Folder; +using included::Folder; } // namespace exported diff --git a/samples/today/schema/MutationObject.ixx b/samples/today/schema/MutationObject.ixx index 5a2fd5ed..80008cd9 100644 --- a/samples/today/schema/MutationObject.ixx +++ b/samples/today/schema/MutationObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Mutation = included::Mutation; +using included::Mutation; } // namespace exported diff --git a/samples/today/schema/NestedTypeObject.ixx b/samples/today/schema/NestedTypeObject.ixx index 095cdf82..7895972c 100644 --- a/samples/today/schema/NestedTypeObject.ixx +++ b/samples/today/schema/NestedTypeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using NestedType = included::NestedType; +using included::NestedType; } // namespace exported diff --git a/samples/today/schema/NodeObject.ixx b/samples/today/schema/NodeObject.ixx index 558df3ef..eafee7d1 100644 --- a/samples/today/schema/NodeObject.ixx +++ b/samples/today/schema/NodeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Node = included::Node; +using included::Node; } // namespace exported diff --git a/samples/today/schema/PageInfoObject.ixx b/samples/today/schema/PageInfoObject.ixx index 7ef13425..f68e2225 100644 --- a/samples/today/schema/PageInfoObject.ixx +++ b/samples/today/schema/PageInfoObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using PageInfo = included::PageInfo; +using included::PageInfo; } // namespace exported diff --git a/samples/today/schema/QueryObject.ixx b/samples/today/schema/QueryObject.ixx index 8a2b3938..5388c782 100644 --- a/samples/today/schema/QueryObject.ixx +++ b/samples/today/schema/QueryObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Query = included::Query; +using included::Query; } // namespace exported diff --git a/samples/today/schema/SubscriptionObject.ixx b/samples/today/schema/SubscriptionObject.ixx index 3c359438..dd90d666 100644 --- a/samples/today/schema/SubscriptionObject.ixx +++ b/samples/today/schema/SubscriptionObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Subscription = included::Subscription; +using included::Subscription; } // namespace exported diff --git a/samples/today/schema/TaskConnectionObject.ixx b/samples/today/schema/TaskConnectionObject.ixx index 57c8c868..1767efeb 100644 --- a/samples/today/schema/TaskConnectionObject.ixx +++ b/samples/today/schema/TaskConnectionObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using TaskConnection = included::TaskConnection; +using included::TaskConnection; } // namespace exported diff --git a/samples/today/schema/TaskEdgeObject.ixx b/samples/today/schema/TaskEdgeObject.ixx index 52d7a41f..61d2bd63 100644 --- a/samples/today/schema/TaskEdgeObject.ixx +++ b/samples/today/schema/TaskEdgeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using TaskEdge = included::TaskEdge; +using included::TaskEdge; } // namespace exported diff --git a/samples/today/schema/TaskObject.ixx b/samples/today/schema/TaskObject.ixx index a6d15c00..8a3b6e0a 100644 --- a/samples/today/schema/TaskObject.ixx +++ b/samples/today/schema/TaskObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using Task = included::Task; +using included::Task; } // namespace exported diff --git a/samples/today/schema/TodaySchema.ixx b/samples/today/schema/TodaySchema.ixx index 1cce90c6..7c1f5d30 100644 --- a/samples/today/schema/TodaySchema.ixx +++ b/samples/today/schema/TodaySchema.ixx @@ -15,124 +15,42 @@ export namespace graphql::today { namespace exported { -using TaskState = included::TaskState; - -constexpr auto getTaskStateNames() noexcept -{ - return included::getTaskStateNames(); -} - -constexpr auto getTaskStateValues() noexcept -{ - return included::getTaskStateValues(); -} - -using CompleteTaskInput= included::CompleteTaskInput; -using ThirdNestedInput= included::ThirdNestedInput; -using FourthNestedInput= included::FourthNestedInput; -using IncludeNullableSelfInput= included::IncludeNullableSelfInput; -using IncludeNonNullableListSelfInput= included::IncludeNonNullableListSelfInput; -using StringOperationFilterInput= included::StringOperationFilterInput; -using SecondNestedInput= included::SecondNestedInput; -using ForwardDeclaredInput= included::ForwardDeclaredInput; -using FirstNestedInput= included::FirstNestedInput; - -using Operations = included::Operations; - -void AddNodeDetails(const std::shared_ptr& typeNode, const std::shared_ptr& schema) -{ - included::AddNodeDetails(typeNode, schema); -} - -void AddUnionTypeDetails(const std::shared_ptr& typeUnionType, const std::shared_ptr& schema) -{ - included::AddUnionTypeDetails(typeUnionType, schema); -} - -void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) -{ - included::AddQueryDetails(typeQuery, schema); -} - -void AddPageInfoDetails(const std::shared_ptr& typePageInfo, const std::shared_ptr& schema) -{ - included::AddPageInfoDetails(typePageInfo, schema); -} - -void AddAppointmentEdgeDetails(const std::shared_ptr& typeAppointmentEdge, const std::shared_ptr& schema) -{ - included::AddAppointmentEdgeDetails(typeAppointmentEdge, schema); -} - -void AddAppointmentConnectionDetails(const std::shared_ptr& typeAppointmentConnection, const std::shared_ptr& schema) -{ - included::AddAppointmentConnectionDetails(typeAppointmentConnection, schema); -} - -void AddTaskEdgeDetails(const std::shared_ptr& typeTaskEdge, const std::shared_ptr& schema) -{ - included::AddTaskEdgeDetails(typeTaskEdge, schema); -} - -void AddTaskConnectionDetails(const std::shared_ptr& typeTaskConnection, const std::shared_ptr& schema) -{ - included::AddTaskConnectionDetails(typeTaskConnection, schema); -} - -void AddFolderEdgeDetails(const std::shared_ptr& typeFolderEdge, const std::shared_ptr& schema) -{ - included::AddFolderEdgeDetails(typeFolderEdge, schema); -} - -void AddFolderConnectionDetails(const std::shared_ptr& typeFolderConnection, const std::shared_ptr& schema) -{ - included::AddFolderConnectionDetails(typeFolderConnection, schema); -} - -void AddCompleteTaskPayloadDetails(const std::shared_ptr& typeCompleteTaskPayload, const std::shared_ptr& schema) -{ - included::AddCompleteTaskPayloadDetails(typeCompleteTaskPayload, schema); -} - -void AddMutationDetails(const std::shared_ptr& typeMutation, const std::shared_ptr& schema) -{ - included::AddMutationDetails(typeMutation, schema); -} - -void AddSubscriptionDetails(const std::shared_ptr& typeSubscription, const std::shared_ptr& schema) -{ - included::AddSubscriptionDetails(typeSubscription, schema); -} - -void AddAppointmentDetails(const std::shared_ptr& typeAppointment, const std::shared_ptr& schema) -{ - included::AddAppointmentDetails(typeAppointment, schema); -} - -void AddTaskDetails(const std::shared_ptr& typeTask, const std::shared_ptr& schema) -{ - included::AddTaskDetails(typeTask, schema); -} - -void AddFolderDetails(const std::shared_ptr& typeFolder, const std::shared_ptr& schema) -{ - included::AddFolderDetails(typeFolder, schema); -} - -void AddNestedTypeDetails(const std::shared_ptr& typeNestedType, const std::shared_ptr& schema) -{ - included::AddNestedTypeDetails(typeNestedType, schema); -} - -void AddExpensiveDetails(const std::shared_ptr& typeExpensive, const std::shared_ptr& schema) -{ - included::AddExpensiveDetails(typeExpensive, schema); -} - -std::shared_ptr GetSchema() -{ - return included::GetSchema(); -} +using included::TaskState; +using included::getTaskStateNames; +using included::getTaskStateValues; + +using included::CompleteTaskInput; +using included::ThirdNestedInput; +using included::FourthNestedInput; +using included::IncludeNullableSelfInput; +using included::IncludeNonNullableListSelfInput; +using included::StringOperationFilterInput; +using included::SecondNestedInput; +using included::ForwardDeclaredInput; +using included::FirstNestedInput; + +using included::Operations; + +using included::AddNodeDetails; +using included::AddUnionTypeDetails; +using included::AddQueryDetails; +using included::AddPageInfoDetails; +using included::AddAppointmentEdgeDetails; +using included::AddAppointmentConnectionDetails; +using included::AddTaskEdgeDetails; +using included::AddTaskConnectionDetails; +using included::AddFolderEdgeDetails; +using included::AddFolderConnectionDetails; +using included::AddCompleteTaskPayloadDetails; +using included::AddMutationDetails; +using included::AddSubscriptionDetails; +using included::AddAppointmentDetails; +using included::AddTaskDetails; +using included::AddFolderDetails; +using included::AddNestedTypeDetails; +using included::AddExpensiveDetails; + +using included::GetSchema; } // namespace exported diff --git a/samples/today/schema/UnionTypeObject.ixx b/samples/today/schema/UnionTypeObject.ixx index dfca5cc6..362b8a41 100644 --- a/samples/today/schema/UnionTypeObject.ixx +++ b/samples/today/schema/UnionTypeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::today::object { namespace exported { -using UnionType = included::UnionType; +using included::UnionType; } // namespace exported diff --git a/samples/validation/schema/AlienObject.ixx b/samples/validation/schema/AlienObject.ixx index fbfb2fe4..fa01c412 100644 --- a/samples/validation/schema/AlienObject.ixx +++ b/samples/validation/schema/AlienObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Alien = included::Alien; +using included::Alien; } // namespace exported diff --git a/samples/validation/schema/ArgumentsObject.ixx b/samples/validation/schema/ArgumentsObject.ixx index b207ec50..e6f5fced 100644 --- a/samples/validation/schema/ArgumentsObject.ixx +++ b/samples/validation/schema/ArgumentsObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Arguments = included::Arguments; +using included::Arguments; } // namespace exported diff --git a/samples/validation/schema/CatObject.ixx b/samples/validation/schema/CatObject.ixx index 0c82760e..e2612a95 100644 --- a/samples/validation/schema/CatObject.ixx +++ b/samples/validation/schema/CatObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Cat = included::Cat; +using included::Cat; } // namespace exported diff --git a/samples/validation/schema/CatOrDogObject.ixx b/samples/validation/schema/CatOrDogObject.ixx index f557c5fc..ee6327b3 100644 --- a/samples/validation/schema/CatOrDogObject.ixx +++ b/samples/validation/schema/CatOrDogObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using CatOrDog = included::CatOrDog; +using included::CatOrDog; } // namespace exported diff --git a/samples/validation/schema/DogObject.ixx b/samples/validation/schema/DogObject.ixx index 4385c5f3..7658ad3b 100644 --- a/samples/validation/schema/DogObject.ixx +++ b/samples/validation/schema/DogObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Dog = included::Dog; +using included::Dog; } // namespace exported diff --git a/samples/validation/schema/DogOrHumanObject.ixx b/samples/validation/schema/DogOrHumanObject.ixx index 5f9c0cad..3b79e779 100644 --- a/samples/validation/schema/DogOrHumanObject.ixx +++ b/samples/validation/schema/DogOrHumanObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using DogOrHuman = included::DogOrHuman; +using included::DogOrHuman; } // namespace exported diff --git a/samples/validation/schema/HumanObject.ixx b/samples/validation/schema/HumanObject.ixx index e3abd321..e8f263a3 100644 --- a/samples/validation/schema/HumanObject.ixx +++ b/samples/validation/schema/HumanObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Human = included::Human; +using included::Human; } // namespace exported diff --git a/samples/validation/schema/HumanOrAlienObject.ixx b/samples/validation/schema/HumanOrAlienObject.ixx index 5a2b5a42..a43fbac6 100644 --- a/samples/validation/schema/HumanOrAlienObject.ixx +++ b/samples/validation/schema/HumanOrAlienObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using HumanOrAlien = included::HumanOrAlien; +using included::HumanOrAlien; } // namespace exported diff --git a/samples/validation/schema/MessageObject.ixx b/samples/validation/schema/MessageObject.ixx index 4857282f..2564a7ec 100644 --- a/samples/validation/schema/MessageObject.ixx +++ b/samples/validation/schema/MessageObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Message = included::Message; +using included::Message; } // namespace exported diff --git a/samples/validation/schema/MutateDogResultObject.ixx b/samples/validation/schema/MutateDogResultObject.ixx index 045dd755..a1191701 100644 --- a/samples/validation/schema/MutateDogResultObject.ixx +++ b/samples/validation/schema/MutateDogResultObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using MutateDogResult = included::MutateDogResult; +using included::MutateDogResult; } // namespace exported diff --git a/samples/validation/schema/MutationObject.ixx b/samples/validation/schema/MutationObject.ixx index f189ff07..f3653039 100644 --- a/samples/validation/schema/MutationObject.ixx +++ b/samples/validation/schema/MutationObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Mutation = included::Mutation; +using included::Mutation; } // namespace exported diff --git a/samples/validation/schema/NodeObject.ixx b/samples/validation/schema/NodeObject.ixx index 5651b3b4..09bfc3fe 100644 --- a/samples/validation/schema/NodeObject.ixx +++ b/samples/validation/schema/NodeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Node = included::Node; +using included::Node; } // namespace exported diff --git a/samples/validation/schema/PetObject.ixx b/samples/validation/schema/PetObject.ixx index fd893248..19fe3ea3 100644 --- a/samples/validation/schema/PetObject.ixx +++ b/samples/validation/schema/PetObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Pet = included::Pet; +using included::Pet; } // namespace exported diff --git a/samples/validation/schema/QueryObject.ixx b/samples/validation/schema/QueryObject.ixx index a2de1cc3..0cc191ee 100644 --- a/samples/validation/schema/QueryObject.ixx +++ b/samples/validation/schema/QueryObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Query = included::Query; +using included::Query; } // namespace exported diff --git a/samples/validation/schema/ResourceObject.ixx b/samples/validation/schema/ResourceObject.ixx index 4c171957..ac491835 100644 --- a/samples/validation/schema/ResourceObject.ixx +++ b/samples/validation/schema/ResourceObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Resource = included::Resource; +using included::Resource; } // namespace exported diff --git a/samples/validation/schema/SentientObject.ixx b/samples/validation/schema/SentientObject.ixx index e7b6d35b..7e19233c 100644 --- a/samples/validation/schema/SentientObject.ixx +++ b/samples/validation/schema/SentientObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Sentient = included::Sentient; +using included::Sentient; } // namespace exported diff --git a/samples/validation/schema/SubscriptionObject.ixx b/samples/validation/schema/SubscriptionObject.ixx index 8a51c9c4..571e57a2 100644 --- a/samples/validation/schema/SubscriptionObject.ixx +++ b/samples/validation/schema/SubscriptionObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::validation::object { namespace exported { -using Subscription = included::Subscription; +using included::Subscription; } // namespace exported diff --git a/samples/validation/schema/ValidationSchema.ixx b/samples/validation/schema/ValidationSchema.ixx index f7baef11..4ecd7eeb 100644 --- a/samples/validation/schema/ValidationSchema.ixx +++ b/samples/validation/schema/ValidationSchema.ixx @@ -15,123 +15,37 @@ export namespace graphql::validation { namespace exported { -using DogCommand = included::DogCommand; - -constexpr auto getDogCommandNames() noexcept -{ - return included::getDogCommandNames(); -} - -constexpr auto getDogCommandValues() noexcept -{ - return included::getDogCommandValues(); -} - -using CatCommand = included::CatCommand; - -constexpr auto getCatCommandNames() noexcept -{ - return included::getCatCommandNames(); -} - -constexpr auto getCatCommandValues() noexcept -{ - return included::getCatCommandValues(); -} - -using ComplexInput= included::ComplexInput; - -using Operations = included::Operations; - -void AddSentientDetails(const std::shared_ptr& typeSentient, const std::shared_ptr& schema) -{ - included::AddSentientDetails(typeSentient, schema); -} - -void AddPetDetails(const std::shared_ptr& typePet, const std::shared_ptr& schema) -{ - included::AddPetDetails(typePet, schema); -} - -void AddNodeDetails(const std::shared_ptr& typeNode, const std::shared_ptr& schema) -{ - included::AddNodeDetails(typeNode, schema); -} - -void AddResourceDetails(const std::shared_ptr& typeResource, const std::shared_ptr& schema) -{ - included::AddResourceDetails(typeResource, schema); -} - -void AddCatOrDogDetails(const std::shared_ptr& typeCatOrDog, const std::shared_ptr& schema) -{ - included::AddCatOrDogDetails(typeCatOrDog, schema); -} - -void AddDogOrHumanDetails(const std::shared_ptr& typeDogOrHuman, const std::shared_ptr& schema) -{ - included::AddDogOrHumanDetails(typeDogOrHuman, schema); -} - -void AddHumanOrAlienDetails(const std::shared_ptr& typeHumanOrAlien, const std::shared_ptr& schema) -{ - included::AddHumanOrAlienDetails(typeHumanOrAlien, schema); -} - -void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) -{ - included::AddQueryDetails(typeQuery, schema); -} - -void AddDogDetails(const std::shared_ptr& typeDog, const std::shared_ptr& schema) -{ - included::AddDogDetails(typeDog, schema); -} - -void AddAlienDetails(const std::shared_ptr& typeAlien, const std::shared_ptr& schema) -{ - included::AddAlienDetails(typeAlien, schema); -} - -void AddHumanDetails(const std::shared_ptr& typeHuman, const std::shared_ptr& schema) -{ - included::AddHumanDetails(typeHuman, schema); -} - -void AddCatDetails(const std::shared_ptr& typeCat, const std::shared_ptr& schema) -{ - included::AddCatDetails(typeCat, schema); -} - -void AddMutationDetails(const std::shared_ptr& typeMutation, const std::shared_ptr& schema) -{ - included::AddMutationDetails(typeMutation, schema); -} - -void AddMutateDogResultDetails(const std::shared_ptr& typeMutateDogResult, const std::shared_ptr& schema) -{ - included::AddMutateDogResultDetails(typeMutateDogResult, schema); -} - -void AddSubscriptionDetails(const std::shared_ptr& typeSubscription, const std::shared_ptr& schema) -{ - included::AddSubscriptionDetails(typeSubscription, schema); -} - -void AddMessageDetails(const std::shared_ptr& typeMessage, const std::shared_ptr& schema) -{ - included::AddMessageDetails(typeMessage, schema); -} - -void AddArgumentsDetails(const std::shared_ptr& typeArguments, const std::shared_ptr& schema) -{ - included::AddArgumentsDetails(typeArguments, schema); -} - -std::shared_ptr GetSchema() -{ - return included::GetSchema(); -} +using included::DogCommand; +using included::getDogCommandNames; +using included::getDogCommandValues; + +using included::CatCommand; +using included::getCatCommandNames; +using included::getCatCommandValues; + +using included::ComplexInput; + +using included::Operations; + +using included::AddSentientDetails; +using included::AddPetDetails; +using included::AddNodeDetails; +using included::AddResourceDetails; +using included::AddCatOrDogDetails; +using included::AddDogOrHumanDetails; +using included::AddHumanOrAlienDetails; +using included::AddQueryDetails; +using included::AddDogDetails; +using included::AddAlienDetails; +using included::AddHumanDetails; +using included::AddCatDetails; +using included::AddMutationDetails; +using included::AddMutateDogResultDetails; +using included::AddSubscriptionDetails; +using included::AddMessageDetails; +using included::AddArgumentsDetails; + +using included::GetSchema; } // namespace exported diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index cba1b99b..cb76a36f 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -653,6 +653,18 @@ export )cpp"; NamespaceScope schemaNamespace { moduleFile, _schemaLoader.getSchemaNamespace(), true }; PendingBlankLine pendingSeparator { moduleFile }; + pendingSeparator.reset(); + if (schemaNamespace.enter()) + { + moduleFile << R"cpp( +using included::)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::GetRequestText; +using included::)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::GetRequestObject; +)cpp"; + pendingSeparator.add(); + } + const auto& operations = _requestLoader.getOperations(); std::unordered_set declaredEnum; @@ -672,14 +684,8 @@ export )cpp"; continue; } - if (schemaNamespace.enter()) - { - moduleFile << std::endl; - } - - moduleFile << R"cpp(using )cpp" << cppType << R"cpp( = included::)cpp" - << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << cppType - << R"cpp(; + moduleFile << R"cpp(using included::)cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::)cpp" << cppType << R"cpp(; )cpp"; } } @@ -709,9 +715,8 @@ export )cpp"; continue; } - moduleFile << R"cpp(using )cpp" << cppType << R"cpp( = included::)cpp" - << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << cppType - << R"cpp(; + moduleFile << R"cpp(using included::)cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::)cpp" << cppType << R"cpp(; )cpp"; } } @@ -735,7 +740,61 @@ export )cpp"; NamespaceScope operationNamespaceScope { moduleFile, getOperationNamespace(operation) }; moduleFile << R"cpp( -using Traits = included::)cpp" +using included::)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::GetRequestText; +using included::)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::GetRequestObject; +using included::)cpp" + << getOperationNamespace(operation) << R"cpp(::GetOperationName; + +)cpp"; + + // Alias all of the enums referenced either in variables or the response. + for (const auto& enumType : _requestLoader.getReferencedEnums(operation)) + { + moduleFile << R"cpp(using included::)cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::)cpp" << _schemaLoader.getCppType(enumType->name()) << R"cpp(; +)cpp"; + + pendingSeparator.add(); + } + + pendingSeparator.reset(); + + // Alias all of the input object structs referenced in variables. + for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) + { + moduleFile << R"cpp(using included::)cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::)cpp" << _schemaLoader.getCppType(inputType.type->name()) + << R"cpp(; +)cpp"; + + pendingSeparator.add(); + } + + pendingSeparator.reset(); + + const auto& variables = _requestLoader.getVariables(operation); + + if (!variables.empty()) + { + moduleFile << R"cpp(using included::)cpp" << getOperationNamespace(operation) + << R"cpp(::Variables; +using included::)cpp" << getOperationNamespace(operation) + << R"cpp(::serializeVariables; +)cpp"; + + pendingSeparator.add(); + } + + pendingSeparator.reset(); + + moduleFile << R"cpp(using included::)cpp" << getOperationNamespace(operation) + << R"cpp(::Response; +using included::)cpp" + << getOperationNamespace(operation) << R"cpp(::parseResponse; + +using included::)cpp" << getOperationNamespace(operation) << R"cpp(::Traits; )cpp"; diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 0e76b294..8b21a3e8 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -727,22 +727,11 @@ export )cpp"; for (const auto& enumType : _loader.getEnumTypes()) { - moduleFile << R"cpp(using )cpp" << enumType.cppType << R"cpp( = included::)cpp" - << enumType.cppType << R"cpp(; - -constexpr auto get)cpp" << enumType.cppType - << R"cpp(Names() noexcept -{ - return included::get)cpp" - << enumType.cppType << R"cpp(Names(); -} - -constexpr auto get)cpp" << enumType.cppType - << R"cpp(Values() noexcept -{ - return included::get)cpp" - << enumType.cppType << R"cpp(Values(); -} + moduleFile << R"cpp(using included::)cpp" << enumType.cppType << R"cpp(; +using included::get)cpp" + << enumType.cppType << R"cpp(Names; +using included::get)cpp" + << enumType.cppType << R"cpp(Values; )cpp"; } @@ -754,8 +743,7 @@ constexpr auto get)cpp" << enumType.cppType for (const auto& inputType : _loader.getInputTypes()) { - moduleFile << R"cpp(using )cpp" << inputType.cppType << R"cpp(= included::)cpp" - << inputType.cppType << R"cpp(; + moduleFile << R"cpp(using included::)cpp" << inputType.cppType << R"cpp(; )cpp"; } @@ -766,7 +754,7 @@ constexpr auto get)cpp" << enumType.cppType { pendingSeparator.reset(); - moduleFile << R"cpp(using Operations = included::Operations; + moduleFile << R"cpp(using included::Operations; )cpp"; } @@ -777,15 +765,7 @@ constexpr auto get)cpp" << enumType.cppType for (const auto& interfaceType : _loader.getInterfaceTypes()) { - moduleFile << R"cpp(void Add)cpp" << interfaceType.cppType - << R"cpp(Details(const std::shared_ptr& type)cpp" - << interfaceType.cppType - << R"cpp(, const std::shared_ptr& schema) -{ - included::Add)cpp" << interfaceType.cppType - << R"cpp(Details(type)cpp" << interfaceType.cppType << R"cpp(, schema); -} - + moduleFile << R"cpp(using included::Add)cpp" << interfaceType.cppType << R"cpp(Details; )cpp"; } } @@ -796,15 +776,7 @@ constexpr auto get)cpp" << enumType.cppType for (const auto& unionType : _loader.getUnionTypes()) { - moduleFile << R"cpp(void Add)cpp" << unionType.cppType - << R"cpp(Details(const std::shared_ptr& type)cpp" - << unionType.cppType - << R"cpp(, const std::shared_ptr& schema) -{ - included::Add)cpp" << unionType.cppType - << R"cpp(Details(type)cpp" << unionType.cppType << R"cpp(, schema); -} - + moduleFile << R"cpp(using included::Add)cpp" << unionType.cppType << R"cpp(Details; )cpp"; } } @@ -815,36 +787,22 @@ constexpr auto get)cpp" << enumType.cppType for (const auto& objectType : _loader.getObjectTypes()) { - moduleFile << R"cpp(void Add)cpp" << objectType.cppType - << R"cpp(Details(const std::shared_ptr& type)cpp" - << objectType.cppType - << R"cpp(, const std::shared_ptr& schema) -{ - included::Add)cpp" << objectType.cppType - << R"cpp(Details(type)cpp" << objectType.cppType << R"cpp(, schema); -} - + moduleFile << R"cpp(using included::Add)cpp" << objectType.cppType << R"cpp(Details; )cpp"; } } if (_loader.isIntrospection()) { - pendingSeparator.reset(); - moduleFile << R"cpp(void AddTypesToSchema(const std::shared_ptr& schema) -{ - included::AddTypesToSchema(schema); -} + moduleFile << R"cpp( +using included::AddTypesToSchema; )cpp"; } else { - pendingSeparator.reset(); - moduleFile << R"cpp(std::shared_ptr GetSchema() -{ - return included::GetSchema(); -} + moduleFile << R"cpp( +using included::GetSchema; )cpp"; } @@ -958,8 +916,8 @@ export namespace )cpp" namespace exported { -using )cpp" << cppType - << R"cpp( = included::)cpp" << cppType << R"cpp(; +using included::)cpp" + << cppType << R"cpp(; } // namespace exported diff --git a/src/introspection/DirectiveObject.ixx b/src/introspection/DirectiveObject.ixx index 3074c61c..97f3dae7 100644 --- a/src/introspection/DirectiveObject.ixx +++ b/src/introspection/DirectiveObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using Directive = included::Directive; +using included::Directive; } // namespace exported diff --git a/src/introspection/EnumValueObject.ixx b/src/introspection/EnumValueObject.ixx index 3fe1aac9..572acd70 100644 --- a/src/introspection/EnumValueObject.ixx +++ b/src/introspection/EnumValueObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using EnumValue = included::EnumValue; +using included::EnumValue; } // namespace exported diff --git a/src/introspection/FieldObject.ixx b/src/introspection/FieldObject.ixx index 6458133e..b98ed284 100644 --- a/src/introspection/FieldObject.ixx +++ b/src/introspection/FieldObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using Field = included::Field; +using included::Field; } // namespace exported diff --git a/src/introspection/InputValueObject.ixx b/src/introspection/InputValueObject.ixx index ffa0ce4e..b3ca2cfd 100644 --- a/src/introspection/InputValueObject.ixx +++ b/src/introspection/InputValueObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using InputValue = included::InputValue; +using included::InputValue; } // namespace exported diff --git a/src/introspection/IntrospectionSchema.ixx b/src/introspection/IntrospectionSchema.ixx index 859747cb..77d96507 100644 --- a/src/introspection/IntrospectionSchema.ixx +++ b/src/introspection/IntrospectionSchema.ixx @@ -15,64 +15,22 @@ export namespace graphql::introspection { namespace exported { -using TypeKind = included::TypeKind; - -constexpr auto getTypeKindNames() noexcept -{ - return included::getTypeKindNames(); -} - -constexpr auto getTypeKindValues() noexcept -{ - return included::getTypeKindValues(); -} - -using DirectiveLocation = included::DirectiveLocation; - -constexpr auto getDirectiveLocationNames() noexcept -{ - return included::getDirectiveLocationNames(); -} - -constexpr auto getDirectiveLocationValues() noexcept -{ - return included::getDirectiveLocationValues(); -} - -void AddSchemaDetails(const std::shared_ptr& typeSchema, const std::shared_ptr& schema) -{ - included::AddSchemaDetails(typeSchema, schema); -} - -void AddTypeDetails(const std::shared_ptr& typeType, const std::shared_ptr& schema) -{ - included::AddTypeDetails(typeType, schema); -} - -void AddFieldDetails(const std::shared_ptr& typeField, const std::shared_ptr& schema) -{ - included::AddFieldDetails(typeField, schema); -} - -void AddInputValueDetails(const std::shared_ptr& typeInputValue, const std::shared_ptr& schema) -{ - included::AddInputValueDetails(typeInputValue, schema); -} - -void AddEnumValueDetails(const std::shared_ptr& typeEnumValue, const std::shared_ptr& schema) -{ - included::AddEnumValueDetails(typeEnumValue, schema); -} - -void AddDirectiveDetails(const std::shared_ptr& typeDirective, const std::shared_ptr& schema) -{ - included::AddDirectiveDetails(typeDirective, schema); -} - -void AddTypesToSchema(const std::shared_ptr& schema) -{ - included::AddTypesToSchema(schema); -} +using included::TypeKind; +using included::getTypeKindNames; +using included::getTypeKindValues; + +using included::DirectiveLocation; +using included::getDirectiveLocationNames; +using included::getDirectiveLocationValues; + +using included::AddSchemaDetails; +using included::AddTypeDetails; +using included::AddFieldDetails; +using included::AddInputValueDetails; +using included::AddEnumValueDetails; +using included::AddDirectiveDetails; + +using included::AddTypesToSchema; } // namespace exported diff --git a/src/introspection/SchemaObject.ixx b/src/introspection/SchemaObject.ixx index b96287b2..063cc3f7 100644 --- a/src/introspection/SchemaObject.ixx +++ b/src/introspection/SchemaObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using Schema = included::Schema; +using included::Schema; } // namespace exported diff --git a/src/introspection/TypeObject.ixx b/src/introspection/TypeObject.ixx index 1c16e7a1..401a9329 100644 --- a/src/introspection/TypeObject.ixx +++ b/src/introspection/TypeObject.ixx @@ -15,7 +15,7 @@ export namespace graphql::introspection::object { namespace exported { -using Type = included::Type; +using included::Type; } // namespace exported From fbcd7280e2a47da9dcccc79b15b66b8510daa461 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 13:20:09 -0700 Subject: [PATCH 035/123] feat(modules): wrap public headers in interface modules --- include/graphqlservice/Client.ixx | 48 ++++++++ include/graphqlservice/GraphQLClient.h | 8 +- include/graphqlservice/GraphQLService.h | 30 +++-- include/graphqlservice/Parse.ixx | 39 +++++++ include/graphqlservice/Response.ixx | 40 +++++++ include/graphqlservice/Service.ixx | 141 ++++++++++++++++++++++++ src/CMakeLists.txt | 52 +++++++-- src/GraphQLService.cpp | 2 + 8 files changed, 332 insertions(+), 28 deletions(-) create mode 100644 include/graphqlservice/Client.ixx create mode 100644 include/graphqlservice/Parse.ixx create mode 100644 include/graphqlservice/Response.ixx create mode 100644 include/graphqlservice/Service.ixx diff --git a/include/graphqlservice/Client.ixx b/include/graphqlservice/Client.ixx new file mode 100644 index 00000000..c22f0a65 --- /dev/null +++ b/include/graphqlservice/Client.ixx @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "GraphQLClient.h" + +export module GraphQL.Client; + +namespace included = graphql::client; + +export namespace graphql::client { + +namespace exported { + +// clang-format off +using included::ErrorLocation; +using included::ErrorPathSegment; +using included::Error; +using included::ServiceResponse; +using included::parseServiceResponse; +using included::TypeModifier; +using included::Variable; + +using included::ModifiedVariable; +using included::IntVariable; +using included::FloatVariable; +using included::StringVariable; +using included::BooleanVariable; +using included::IdVariable; +using included::ScalarVariable; + +using included::Response; + +using included::ModifiedResponse; +using included::IntResponse; +using included::FloatResponse; +using included::StringResponse; +using included::BooleanResponse; +using included::IdResponse; +using included::ScalarResponse; +// clang-format on + +} // namespace exported + +using namespace exported; + +} // namespace graphql::included diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index 2adf34e7..afc0caa2 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -83,7 +83,7 @@ template <> GRAPHQLCLIENT_EXPORT response::Value Variable::serialize(response::Value&& value); #endif // GRAPHQL_DLLEXPORTS -namespace { +inline namespace modified_variable { // These types are used as scalar variables even though they are represented with a class. template @@ -234,7 +234,7 @@ using BooleanVariable = ModifiedVariable; using IdVariable = ModifiedVariable; using ScalarVariable = ModifiedVariable; -} // namespace +} // namespace modified_variable // Parse a single response output value. This is the inverse of Variable for output types instead of // input types. @@ -261,7 +261,7 @@ template <> GRAPHQLCLIENT_EXPORT response::Value Response::parse(response::Value&& response); #endif // GRAPHQL_DLLEXPORTS -namespace { +inline namespace modified_response { // Parse response output values with chained type modifiers that add nullable or list wrappers. // This is the inverse of ModifiedVariable for output types instead of input types. @@ -344,7 +344,7 @@ using BooleanResponse = ModifiedResponse; using IdResponse = ModifiedResponse; using ScalarResponse = ModifiedResponse; -} // namespace +} // namespace modified_response } // namespace graphql::client #endif // GRAPHQLCLIENT_H diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index a4843924..9561eb86 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -120,18 +120,16 @@ struct [[nodiscard("unnecessary construction")]] RequestState inline namespace keywords { -using namespace std::literals; - -constexpr std::string_view strData { "data"sv }; -constexpr std::string_view strErrors { "errors"sv }; -constexpr std::string_view strMessage { "message"sv }; -constexpr std::string_view strLocations { "locations"sv }; -constexpr std::string_view strLine { "line"sv }; -constexpr std::string_view strColumn { "column"sv }; -constexpr std::string_view strPath { "path"sv }; -constexpr std::string_view strQuery { "query"sv }; -constexpr std::string_view strMutation { "mutation"sv }; -constexpr std::string_view strSubscription { "subscription"sv }; +constexpr std::string_view strData { "data" }; +constexpr std::string_view strErrors { "errors" }; +constexpr std::string_view strMessage { "message" }; +constexpr std::string_view strLocations { "locations" }; +constexpr std::string_view strLine { "line" }; +constexpr std::string_view strColumn { "column" }; +constexpr std::string_view strPath { "path" }; +constexpr std::string_view strQuery { "query" }; +constexpr std::string_view strMutation { "mutation" }; +constexpr std::string_view strSubscription { "subscription" }; } // namespace keywords @@ -633,7 +631,7 @@ GRAPHQLSERVICE_EXPORT response::Value Argument::convert( const response::Value& value); #endif // GRAPHQL_DLLEXPORTS -namespace { +inline namespace modified_argument { // These types are used as scalar arguments even though they are represented with a class. template @@ -849,7 +847,7 @@ using BooleanArgument = ModifiedArgument; using IdArgument = ModifiedArgument; using ScalarArgument = ModifiedArgument; -} // namespace +} // namespace modified_argument // Each type should handle fragments with type conditions matching its own // name and any inheritted interfaces. @@ -947,7 +945,7 @@ template <> GRAPHQLSERVICE_EXPORT void Result::validateScalar(const response::Value& value); #endif // GRAPHQL_DLLEXPORTS -namespace { +inline namespace modified_result { // Test if this Type is Object. template @@ -1319,7 +1317,7 @@ using IdResult = ModifiedResult; using ScalarResult = ModifiedResult; using ObjectResult = ModifiedResult; -} // namespace +} // namespace modified_result // Subscription callbacks receive the response::Value representing the result of evaluating the // SelectionSet against the payload. diff --git a/include/graphqlservice/Parse.ixx b/include/graphqlservice/Parse.ixx new file mode 100644 index 00000000..284a21a3 --- /dev/null +++ b/include/graphqlservice/Parse.ixx @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "GraphQLParse.h" + +export module GraphQL.Parse; + +namespace included = graphql::peg; + +export namespace graphql { + +namespace peg { + +namespace exported { + +// clang-format off +using included::ast_node; +using included::ast_input; +using included::ast; + +constexpr std::size_t c_defaultDepthLimit = included::c_defaultDepthLimit; + +using included::parseSchemaString; +using included::parseSchemaFile; +using included::parseString; +using included::parseFile; +// clang-format on + +} // namespace exported + +using namespace exported; + +} // namespace peg + +using graphql::operator"" _graphql; + +} // namespace graphql diff --git a/include/graphqlservice/Response.ixx b/include/graphqlservice/Response.ixx new file mode 100644 index 00000000..5bf1834a --- /dev/null +++ b/include/graphqlservice/Response.ixx @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "GraphQLResponse.h" + +export module GraphQL.Response; + +namespace included = graphql::response; + +export namespace graphql::response { + +namespace exported { + +// clang-format off +using included::Type; + +using included::MapType; +using included::ListType; +using included::StringType; +using included::BooleanType; +using included::IntType; +using included::FloatType; +using included::ScalarType; + +using included::IdType; + +using included::ValueTypeTraits; +using included::Value; +using included::AwaitableValue; + +using included::Writer; +// clang-format on + +} // namespace exported + +using namespace exported; + +} // namespace graphql::response diff --git a/include/graphqlservice/Service.ixx b/include/graphqlservice/Service.ixx new file mode 100644 index 00000000..67e6e48d --- /dev/null +++ b/include/graphqlservice/Service.ixx @@ -0,0 +1,141 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "GraphQLService.h" + +export module GraphQL.Service; + +namespace included = graphql::service; + +export namespace graphql { + +namespace schema { + +namespace exported { + +using schema::Schema; + +} // namespace exported + +using namespace exported; + +} // namespace schema + +namespace service { + +namespace exported { + +// clang-format off +using included::schema_location; +using included::path_segment; +using included::field_path; + +using included::error_path; +using included::buildErrorPath; + +using included::schema_error; +using included::buildErrorValues; + +using included::schema_exception; +using included::unimplemented_method; + +using included::RequestState; + +constexpr std::string_view strData = included::strData; +constexpr std::string_view strErrors = included::strErrors; +constexpr std::string_view strMessage = included::strMessage; +constexpr std::string_view strLocations = included::strLocations; +constexpr std::string_view strLine = included::strLine; +constexpr std::string_view strColumn = included::strColumn; +constexpr std::string_view strPath = included::strPath; +constexpr std::string_view strQuery = included::strQuery; +constexpr std::string_view strMutation = included::strMutation; +constexpr std::string_view strSubscription = included::strSubscription; + +using included::ResolverContext; + +using included::await_worker_thread; +using included::await_worker_queue; +using included::await_async; + +using included::Directives; +using included::FragmentDefinitionDirectiveStack; +using included::FragmentSpreadDirectiveStack; + +using included::SelectionSetParams; +using included::FieldParams; + +using included::AwaitableScalar; +using included::AwaitableObject; + +using included::Fragment; +using included::FragmentMap; + +using included::ResolverParams; +using included::ResolverResult; +using included::AwaitableResolver; +using included::Resolver; +using included::ResolverMap; + +using included::TypeModifier; +using included::Argument; + +using included::ModifiedArgument; +using included::IntArgument; +using included::FloatArgument; +using included::StringArgument; +using included::BooleanArgument; +using included::IdArgument; +using included::ScalarArgument; + +using included::TypeNames; +using included::Object; +using included::Result; + +using included::ModifiedResult; +using included::IntResult; +using included::FloatResult; +using included::StringResult; +using included::BooleanResult; +using included::IdResult; +using included::ScalarResult; +using included::ObjectResult; + +using included::SubscriptionCallback; +using included::SubscriptionKey; +using included::SubscriptionName; + +using included::AwaitableSubscribe; +using included::AwaitableUnsubscribe; +using included::AwaitableDeliver; + +using included::RequestResolveParams; +using included::RequestSubscribeParams; +using included::RequestUnsubscribeParams; + +using included::SubscriptionArguments; +using included::SubscriptionArgumentFilterCallback; +using included::SubscriptionDirectiveFilterCallback; +using included::SubscriptionFilter; + +using included::RequestDeliverFilter; +using included::RequestDeliverParams; + +using included::TypeMap; +using included::OperationData; +using included::SubscriptionData; + +using included::SubscriptionPlaceholder; + +using included::Request; +// clang-format on + +} // namespace exported + +using namespace exported; + +} // namespace service + +} // namespace graphql diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 850b29b3..4e9efbb0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -170,6 +170,17 @@ add_library(graphqlpeg SyntaxTree.cpp) add_library(cppgraphqlgen::graphqlpeg ALIAS graphqlpeg) target_compile_features(graphqlpeg PUBLIC cxx_std_20) target_link_libraries(graphqlpeg PUBLIC taocpp::pegtl) +target_sources(graphqlpeg + PUBLIC FILE_SET HEADERS + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/GraphQLParse.h + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/Parse.ixx) target_include_directories(graphqlpeg PUBLIC $ $) @@ -197,6 +208,17 @@ target_include_directories(graphqlresponse PUBLIC $ $) target_link_libraries(graphqlresponse PUBLIC graphql_internal_modules) +target_sources(graphqlresponse + PUBLIC FILE_SET HEADERS + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/GraphQLResponse.h + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/Response.ixx) if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqlresponse) @@ -385,6 +407,17 @@ target_link_libraries(graphqlservice PUBLIC graphqlpeg graphqlresponse Threads::Threads) +target_sources(graphqlservice + PUBLIC FILE_SET HEADERS + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/GraphQLService.h + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/Service.ixx) if(GRAPHQL_UPDATE_SAMPLES) add_dependencies(graphqlservice copy_introspection_schema_headers) @@ -413,6 +446,17 @@ target_compile_features(graphqlclient PUBLIC cxx_std_20) target_link_libraries(graphqlclient PUBLIC graphqlpeg graphqlresponse) +target_sources(graphqlclient + PUBLIC FILE_SET HEADERS + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/GraphQLClient.h + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/Client.ixx) if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqlclient) @@ -473,14 +517,6 @@ install(TARGETS CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}) -install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/GraphQLClient.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/GraphQLParse.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/GraphQLResponse.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/GraphQLService.h - CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} - DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}/graphqlservice) - # graphqljson if(BUILD_GRAPHQLJSON) target_link_libraries(graphqljson PUBLIC graphqlresponse) diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index e45f3349..af87a2c3 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -12,6 +12,8 @@ #include #include +using namespace std::literals; + namespace graphql::service { void addErrorMessage(std::string&& message, response::Value& error) From d0e48fdd301b81b8894bd76f161ea4e10a6b0faa Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 13:59:48 -0700 Subject: [PATCH 036/123] chore(modules): test with TodayMock as a module --- samples/client/benchmark.cpp | 9 ++-- samples/today/CMakeLists.txt | 10 +++- samples/today/TodayMock.cpp | 18 +++---- samples/today/{TodayMock.h => TodayMock.ixx} | 56 ++++++++++++-------- samples/today/benchmark.cpp | 6 ++- samples/today/sample.cpp | 6 ++- test/ClientTests.cpp | 16 ++++-- test/CoroutineTests.cpp | 7 ++- test/NoIntrospectionTests.cpp | 7 ++- test/TodayTests.cpp | 7 ++- 10 files changed, 91 insertions(+), 51 deletions(-) rename samples/today/{TodayMock.h => TodayMock.ixx} (91%) diff --git a/samples/client/benchmark.cpp b/samples/client/benchmark.cpp index ad7f9537..a677d461 100644 --- a/samples/client/benchmark.cpp +++ b/samples/client/benchmark.cpp @@ -1,9 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "BenchmarkClient.h" -#include "TodayMock.h" - #include #include #include @@ -13,6 +10,12 @@ #include #include +import GraphQL.Client; +import GraphQL.Parse; + +import GraphQL.Today.Mock; +import GraphQL.Benchmark.BenchmarkClient; + using namespace graphql; using namespace std::literals; diff --git a/samples/today/CMakeLists.txt b/samples/today/CMakeLists.txt index c3b9b2bb..ff5bbace 100644 --- a/samples/today/CMakeLists.txt +++ b/samples/today/CMakeLists.txt @@ -6,14 +6,20 @@ cmake_minimum_required(VERSION 3.28) # todaygraphql add_subdirectory(schema) add_library(todaygraphql STATIC TodayMock.cpp) +target_compile_features(todaygraphql PUBLIC cxx_std_20) target_link_libraries(todaygraphql PUBLIC today_schema) -target_include_directories(todaygraphql PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_sources(todaygraphql PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.ixx) # todaygraphql_nointrospection add_subdirectory(nointrospection) add_library(todaygraphql_nointrospection STATIC TodayMock.cpp) +target_compile_features(todaygraphql_nointrospection PUBLIC cxx_std_20) target_link_libraries(todaygraphql_nointrospection PUBLIC today_nointrospection_schema) -target_include_directories(todaygraphql_nointrospection PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_sources(todaygraphql_nointrospection PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.ixx) if(MSVC) # warning C4702: unreachable code diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index 53b0b35b..27887fdd 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -1,20 +1,20 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "TodayMock.h" - -#include "AppointmentConnectionObject.h" -#include "CompleteTaskPayloadObject.h" -#include "ExpensiveObject.h" -#include "FolderConnectionObject.h" -#include "NestedTypeObject.h" -#include "TaskConnectionObject.h" -#include "UnionTypeObject.h" +module; #include #include +#include +#include #include #include +#include +#include + +module GraphQL.Today.Mock; + +import GraphQL.Response; namespace graphql::today { diff --git a/samples/today/TodayMock.h b/samples/today/TodayMock.ixx similarity index 91% rename from samples/today/TodayMock.h rename to samples/today/TodayMock.ixx index 60f97fa1..adb81fd4 100644 --- a/samples/today/TodayMock.h +++ b/samples/today/TodayMock.ixx @@ -1,30 +1,44 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#pragma once - -#ifndef TODAYMOCK_H -#define TODAYMOCK_H - -#include "TodaySchema.h" - -#include "AppointmentEdgeObject.h" -#include "AppointmentObject.h" -#include "FolderEdgeObject.h" -#include "FolderObject.h" -#include "MutationObject.h" -#include "NodeObject.h" -#include "PageInfoObject.h" -#include "QueryObject.h" -#include "SubscriptionObject.h" -#include "TaskEdgeObject.h" -#include "TaskObject.h" +module; #include +#include +#include +#include #include +#include #include - -namespace graphql::today { +#include + +export module GraphQL.Today.Mock; + +import GraphQL.Response; +import GraphQL.Service; + +export import GraphQL.Today.TodaySchema; + +export import GraphQL.Today.AppointmentEdgeObject; +export import GraphQL.Today.AppointmentObject; +export import GraphQL.Today.AppointmentConnectionObject; +export import GraphQL.Today.CompleteTaskPayloadObject; +export import GraphQL.Today.ExpensiveObject; +export import GraphQL.Today.FolderEdgeObject; +export import GraphQL.Today.FolderObject; +export import GraphQL.Today.FolderConnectionObject; +export import GraphQL.Today.MutationObject; +export import GraphQL.Today.NestedTypeObject; +export import GraphQL.Today.NodeObject; +export import GraphQL.Today.PageInfoObject; +export import GraphQL.Today.QueryObject; +export import GraphQL.Today.SubscriptionObject; +export import GraphQL.Today.TaskConnectionObject; +export import GraphQL.Today.TaskEdgeObject; +export import GraphQL.Today.TaskObject; +export import GraphQL.Today.UnionTypeObject; + +export namespace graphql::today { // These IDs are hard-coded in every test which uses TodayMock. const response::IdType& getFakeAppointmentId() noexcept; @@ -411,5 +425,3 @@ class EmptyOperations : public service::Request }; } // namespace graphql::today - -#endif // TODAYMOCK_H diff --git a/samples/today/benchmark.cpp b/samples/today/benchmark.cpp index dff6e9c8..5c2dd588 100644 --- a/samples/today/benchmark.cpp +++ b/samples/today/benchmark.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "TodayMock.h" - #include "graphqlservice/JSONResponse.h" #include @@ -13,6 +11,10 @@ #include #include +import GraphQL.Parse; + +import GraphQL.Today.Mock; + using namespace graphql; using namespace std::literals; diff --git a/samples/today/sample.cpp b/samples/today/sample.cpp index e47f6bda..e665d0ba 100644 --- a/samples/today/sample.cpp +++ b/samples/today/sample.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "TodayMock.h" - #include "graphqlservice/JSONResponse.h" #include @@ -10,6 +8,10 @@ #include #include +import GraphQL.Parse; + +import GraphQL.Today.Mock; + using namespace graphql; int main(int argc, char** argv) diff --git a/test/ClientTests.cpp b/test/ClientTests.cpp index 0294c00d..db52176f 100644 --- a/test/ClientTests.cpp +++ b/test/ClientTests.cpp @@ -3,13 +3,19 @@ #include -#include "MutateClient.h" -#include "QueryClient.h" -#include "SubscribeClient.h" -#include "TodayMock.h" - #include #include +#include + +import GraphQL.Parse; +import GraphQL.Response; +import GraphQL.Client; + +import GraphQL.Mutate.MutateClient; +import GraphQL.Query.QueryClient; +import GraphQL.Subscribe.SubscribeClient; + +import GraphQL.Today.Mock; using namespace graphql; diff --git a/test/CoroutineTests.cpp b/test/CoroutineTests.cpp index 60933449..e7b51f45 100644 --- a/test/CoroutineTests.cpp +++ b/test/CoroutineTests.cpp @@ -3,12 +3,15 @@ #include -#include "TodayMock.h" - #include "graphqlservice/JSONResponse.h" #include +import GraphQL.Parse; +import GraphQL.Service; + +import GraphQL.Today.Mock; + using namespace graphql; using namespace std::literals; diff --git a/test/NoIntrospectionTests.cpp b/test/NoIntrospectionTests.cpp index 2fc72754..d09cf9cc 100644 --- a/test/NoIntrospectionTests.cpp +++ b/test/NoIntrospectionTests.cpp @@ -3,13 +3,16 @@ #include -#include "TodayMock.h" - #include "graphqlservice/JSONResponse.h" #include #include +import GraphQL.Parse; +import GraphQL.Service; + +import GraphQL.Today.Mock; + using namespace graphql; using namespace std::literals; diff --git a/test/TodayTests.cpp b/test/TodayTests.cpp index c38852ea..586cb6cb 100644 --- a/test/TodayTests.cpp +++ b/test/TodayTests.cpp @@ -3,13 +3,16 @@ #include -#include "TodayMock.h" - #include "graphqlservice/JSONResponse.h" #include #include +import GraphQL.Parse; +import GraphQL.Service; + +import GraphQL.Today.Mock; + using namespace graphql; using namespace std::literals; From efd938dd51713e16e0d359478682c8a6e1395f57 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 14:22:12 -0700 Subject: [PATCH 037/123] fix(modules): try re-exporting modules referenced in TodayMock.ixx --- samples/today/TodayMock.ixx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/today/TodayMock.ixx b/samples/today/TodayMock.ixx index adb81fd4..f6ff4cb9 100644 --- a/samples/today/TodayMock.ixx +++ b/samples/today/TodayMock.ixx @@ -14,8 +14,8 @@ module; export module GraphQL.Today.Mock; -import GraphQL.Response; -import GraphQL.Service; +export import GraphQL.Response; +export import GraphQL.Service; export import GraphQL.Today.TodaySchema; From ac633196653158d79eb3992567a624402b29bfb0 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 14:35:15 -0700 Subject: [PATCH 038/123] fix(modules): try to fix CI build breaks in MSVC and GCC --- samples/today/TodayMock.cpp | 2 -- samples/today/TodayMock.ixx | 7 ++++--- src/CMakeLists.txt | 12 ++++++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index 27887fdd..e41d2582 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -14,8 +14,6 @@ module; module GraphQL.Today.Mock; -import GraphQL.Response; - namespace graphql::today { const response::IdType& getFakeAppointmentId() noexcept diff --git a/samples/today/TodayMock.ixx b/samples/today/TodayMock.ixx index f6ff4cb9..2a4af79f 100644 --- a/samples/today/TodayMock.ixx +++ b/samples/today/TodayMock.ixx @@ -19,6 +19,10 @@ export import GraphQL.Service; export import GraphQL.Today.TodaySchema; +export import GraphQL.Today.QueryObject; +export import GraphQL.Today.MutationObject; +export import GraphQL.Today.SubscriptionObject; + export import GraphQL.Today.AppointmentEdgeObject; export import GraphQL.Today.AppointmentObject; export import GraphQL.Today.AppointmentConnectionObject; @@ -27,12 +31,9 @@ export import GraphQL.Today.ExpensiveObject; export import GraphQL.Today.FolderEdgeObject; export import GraphQL.Today.FolderObject; export import GraphQL.Today.FolderConnectionObject; -export import GraphQL.Today.MutationObject; export import GraphQL.Today.NestedTypeObject; export import GraphQL.Today.NodeObject; export import GraphQL.Today.PageInfoObject; -export import GraphQL.Today.QueryObject; -export import GraphQL.Today.SubscriptionObject; export import GraphQL.Today.TaskConnectionObject; export import GraphQL.Today.TaskEdgeObject; export import GraphQL.Today.TaskObject; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4e9efbb0..4862ae6a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -517,6 +517,18 @@ install(TARGETS CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}) +if(WIN32 AND BUILD_SHARED_LIBS) + install(TARGETS + graphqlpeg_version + graphqlresponse_version + graphqlservice_version + graphqlclient_version + graphqljson_version + EXPORT cppgraphqlgen-targets + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib) +endif() + # graphqljson if(BUILD_GRAPHQLJSON) target_link_libraries(graphqljson PUBLIC graphqlresponse) From ba0dd2de0afaa0be2b9a5f5691228113ecac5a1d Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 14:45:41 -0700 Subject: [PATCH 039/123] fix(modules): change import order so TodaySchema is last --- samples/today/TodayMock.ixx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/today/TodayMock.ixx b/samples/today/TodayMock.ixx index 2a4af79f..a9cc7cb7 100644 --- a/samples/today/TodayMock.ixx +++ b/samples/today/TodayMock.ixx @@ -17,12 +17,6 @@ export module GraphQL.Today.Mock; export import GraphQL.Response; export import GraphQL.Service; -export import GraphQL.Today.TodaySchema; - -export import GraphQL.Today.QueryObject; -export import GraphQL.Today.MutationObject; -export import GraphQL.Today.SubscriptionObject; - export import GraphQL.Today.AppointmentEdgeObject; export import GraphQL.Today.AppointmentObject; export import GraphQL.Today.AppointmentConnectionObject; @@ -39,6 +33,12 @@ export import GraphQL.Today.TaskEdgeObject; export import GraphQL.Today.TaskObject; export import GraphQL.Today.UnionTypeObject; +export import GraphQL.Today.QueryObject; +export import GraphQL.Today.MutationObject; +export import GraphQL.Today.SubscriptionObject; + +export import GraphQL.Today.TodaySchema; + export namespace graphql::today { // These IDs are hard-coded in every test which uses TodayMock. From 957f6a31afbe828359fba987d9b9a2f38edb2b21 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 15:45:06 -0700 Subject: [PATCH 040/123] fix(modules): get rid of intermediate exported namespaces --- include/graphqlservice/Client.ixx | 60 +-- include/graphqlservice/Parse.ixx | 26 +- include/graphqlservice/Response.ixx | 32 +- include/graphqlservice/Service.ixx | 222 ++++---- include/graphqlservice/internal/Awaitable.ixx | 10 +- include/graphqlservice/internal/Base64.ixx | 10 +- include/graphqlservice/internal/Grammar.ixx | 484 +++++++++--------- .../graphqlservice/internal/Introspection.ixx | 20 +- include/graphqlservice/internal/Schema.ixx | 51 +- include/graphqlservice/internal/SortedMap.ixx | 24 +- .../graphqlservice/internal/SyntaxTree.ixx | 8 +- include/graphqlservice/internal/Version.ixx | 15 +- .../introspection/DirectiveObject.ixx | 10 +- .../introspection/EnumValueObject.ixx | 10 +- .../introspection/FieldObject.ixx | 10 +- .../introspection/InputValueObject.ixx | 10 +- .../introspection/IntrospectionSchema.ixx | 38 +- .../introspection/SchemaObject.ixx | 10 +- .../introspection/TypeObject.ixx | 10 +- samples/client/benchmark/BenchmarkClient.ixx | 23 +- .../client/multiple/MultipleQueriesClient.ixx | 85 ++- samples/client/mutate/MutateClient.ixx | 35 +- .../client/nestedinput/NestedInputClient.ixx | 43 +- samples/client/query/QueryClient.ixx | 27 +- samples/client/subscribe/SubscribeClient.ixx | 23 +- samples/learn/schema/CharacterObject.ixx | 10 +- samples/learn/schema/DroidObject.ixx | 10 +- samples/learn/schema/HumanObject.ixx | 10 +- samples/learn/schema/MutationObject.ixx | 10 +- samples/learn/schema/QueryObject.ixx | 10 +- samples/learn/schema/ReviewObject.ixx | 10 +- samples/learn/schema/StarWarsSchema.ixx | 30 +- samples/proxy/query/ProxyClient.ixx | 27 +- samples/proxy/schema/ProxySchema.ixx | 12 +- samples/proxy/schema/QueryObject.ixx | 10 +- .../AppointmentConnectionObject.ixx | 10 +- .../nointrospection/AppointmentEdgeObject.ixx | 10 +- .../nointrospection/AppointmentObject.ixx | 10 +- .../CompleteTaskPayloadObject.ixx | 10 +- .../today/nointrospection/ExpensiveObject.ixx | 10 +- .../FolderConnectionObject.ixx | 10 +- .../nointrospection/FolderEdgeObject.ixx | 10 +- .../today/nointrospection/FolderObject.ixx | 10 +- .../today/nointrospection/MutationObject.ixx | 10 +- .../nointrospection/NestedTypeObject.ixx | 10 +- samples/today/nointrospection/NodeObject.ixx | 10 +- .../today/nointrospection/PageInfoObject.ixx | 10 +- samples/today/nointrospection/QueryObject.ixx | 10 +- .../nointrospection/SubscriptionObject.ixx | 10 +- .../nointrospection/TaskConnectionObject.ixx | 10 +- .../today/nointrospection/TaskEdgeObject.ixx | 10 +- samples/today/nointrospection/TaskObject.ixx | 10 +- samples/today/nointrospection/TodaySchema.ixx | 78 ++- .../today/nointrospection/UnionTypeObject.ixx | 10 +- .../schema/AppointmentConnectionObject.ixx | 10 +- .../today/schema/AppointmentEdgeObject.ixx | 10 +- samples/today/schema/AppointmentObject.ixx | 10 +- .../schema/CompleteTaskPayloadObject.ixx | 10 +- samples/today/schema/ExpensiveObject.ixx | 10 +- .../today/schema/FolderConnectionObject.ixx | 10 +- samples/today/schema/FolderEdgeObject.ixx | 10 +- samples/today/schema/FolderObject.ixx | 10 +- samples/today/schema/MutationObject.ixx | 10 +- samples/today/schema/NestedTypeObject.ixx | 10 +- samples/today/schema/NodeObject.ixx | 10 +- samples/today/schema/PageInfoObject.ixx | 10 +- samples/today/schema/QueryObject.ixx | 10 +- samples/today/schema/SubscriptionObject.ixx | 10 +- samples/today/schema/TaskConnectionObject.ixx | 10 +- samples/today/schema/TaskEdgeObject.ixx | 10 +- samples/today/schema/TaskObject.ixx | 10 +- samples/today/schema/TodaySchema.ixx | 78 ++- samples/today/schema/UnionTypeObject.ixx | 10 +- samples/validation/schema/AlienObject.ixx | 10 +- samples/validation/schema/ArgumentsObject.ixx | 10 +- samples/validation/schema/CatObject.ixx | 10 +- samples/validation/schema/CatOrDogObject.ixx | 10 +- samples/validation/schema/DogObject.ixx | 10 +- .../validation/schema/DogOrHumanObject.ixx | 10 +- samples/validation/schema/HumanObject.ixx | 10 +- .../validation/schema/HumanOrAlienObject.ixx | 10 +- samples/validation/schema/MessageObject.ixx | 10 +- .../schema/MutateDogResultObject.ixx | 10 +- samples/validation/schema/MutationObject.ixx | 10 +- samples/validation/schema/NodeObject.ixx | 10 +- samples/validation/schema/PetObject.ixx | 10 +- samples/validation/schema/QueryObject.ixx | 10 +- samples/validation/schema/ResourceObject.ixx | 10 +- samples/validation/schema/SentientObject.ixx | 10 +- .../validation/schema/SubscriptionObject.ixx | 10 +- .../validation/schema/ValidationSchema.ixx | 68 ++- src/ClientGenerator.cpp | 66 +-- src/SchemaGenerator.cpp | 54 +- src/introspection/DirectiveObject.ixx | 10 +- src/introspection/EnumValueObject.ixx | 10 +- src/introspection/FieldObject.ixx | 10 +- src/introspection/InputValueObject.ixx | 10 +- src/introspection/IntrospectionSchema.ixx | 38 +- src/introspection/SchemaObject.ixx | 10 +- src/introspection/TypeObject.ixx | 10 +- 100 files changed, 809 insertions(+), 1598 deletions(-) diff --git a/include/graphqlservice/Client.ixx b/include/graphqlservice/Client.ixx index c22f0a65..aa3f6814 100644 --- a/include/graphqlservice/Client.ixx +++ b/include/graphqlservice/Client.ixx @@ -7,42 +7,34 @@ module; export module GraphQL.Client; -namespace included = graphql::client; - export namespace graphql::client { -namespace exported { - // clang-format off -using included::ErrorLocation; -using included::ErrorPathSegment; -using included::Error; -using included::ServiceResponse; -using included::parseServiceResponse; -using included::TypeModifier; -using included::Variable; - -using included::ModifiedVariable; -using included::IntVariable; -using included::FloatVariable; -using included::StringVariable; -using included::BooleanVariable; -using included::IdVariable; -using included::ScalarVariable; - -using included::Response; - -using included::ModifiedResponse; -using included::IntResponse; -using included::FloatResponse; -using included::StringResponse; -using included::BooleanResponse; -using included::IdResponse; -using included::ScalarResponse; +using client::ErrorLocation; +using client::ErrorPathSegment; +using client::Error; +using client::ServiceResponse; +using client::parseServiceResponse; +using client::TypeModifier; +using client::Variable; + +using client::ModifiedVariable; +using client::IntVariable; +using client::FloatVariable; +using client::StringVariable; +using client::BooleanVariable; +using client::IdVariable; +using client::ScalarVariable; + +using client::Response; + +using client::ModifiedResponse; +using client::IntResponse; +using client::FloatResponse; +using client::StringResponse; +using client::BooleanResponse; +using client::IdResponse; +using client::ScalarResponse; // clang-format on -} // namespace exported - -using namespace exported; - -} // namespace graphql::included +} // namespace graphql::client diff --git a/include/graphqlservice/Parse.ixx b/include/graphqlservice/Parse.ixx index 284a21a3..bd699cf1 100644 --- a/include/graphqlservice/Parse.ixx +++ b/include/graphqlservice/Parse.ixx @@ -7,30 +7,26 @@ module; export module GraphQL.Parse; -namespace included = graphql::peg; - export namespace graphql { namespace peg { -namespace exported { - // clang-format off -using included::ast_node; -using included::ast_input; -using included::ast; +using peg::ast_node; +using peg::ast_input; +using peg::ast; -constexpr std::size_t c_defaultDepthLimit = included::c_defaultDepthLimit; +namespace constants { -using included::parseSchemaString; -using included::parseSchemaFile; -using included::parseString; -using included::parseFile; -// clang-format on +constexpr std::size_t c_defaultDepthLimit = peg::c_defaultDepthLimit; -} // namespace exported +} // namespace constants -using namespace exported; +using peg::parseSchemaString; +using peg::parseSchemaFile; +using peg::parseString; +using peg::parseFile; +// clang-format on } // namespace peg diff --git a/include/graphqlservice/Response.ixx b/include/graphqlservice/Response.ixx index 5bf1834a..208368e6 100644 --- a/include/graphqlservice/Response.ixx +++ b/include/graphqlservice/Response.ixx @@ -11,30 +11,24 @@ namespace included = graphql::response; export namespace graphql::response { -namespace exported { - // clang-format off -using included::Type; +using response::Type; -using included::MapType; -using included::ListType; -using included::StringType; -using included::BooleanType; -using included::IntType; -using included::FloatType; -using included::ScalarType; +using response::MapType; +using response::ListType; +using response::StringType; +using response::BooleanType; +using response::IntType; +using response::FloatType; +using response::ScalarType; -using included::IdType; +using response::IdType; -using included::ValueTypeTraits; -using included::Value; -using included::AwaitableValue; +using response::ValueTypeTraits; +using response::Value; +using response::AwaitableValue; -using included::Writer; +using response::Writer; // clang-format on -} // namespace exported - -using namespace exported; - } // namespace graphql::response diff --git a/include/graphqlservice/Service.ixx b/include/graphqlservice/Service.ixx index 67e6e48d..1a4429de 100644 --- a/include/graphqlservice/Service.ixx +++ b/include/graphqlservice/Service.ixx @@ -7,134 +7,126 @@ module; export module GraphQL.Service; -namespace included = graphql::service; - export namespace graphql { namespace schema { -namespace exported { - using schema::Schema; -} // namespace exported - -using namespace exported; - } // namespace schema namespace service { -namespace exported { - // clang-format off -using included::schema_location; -using included::path_segment; -using included::field_path; - -using included::error_path; -using included::buildErrorPath; - -using included::schema_error; -using included::buildErrorValues; - -using included::schema_exception; -using included::unimplemented_method; - -using included::RequestState; - -constexpr std::string_view strData = included::strData; -constexpr std::string_view strErrors = included::strErrors; -constexpr std::string_view strMessage = included::strMessage; -constexpr std::string_view strLocations = included::strLocations; -constexpr std::string_view strLine = included::strLine; -constexpr std::string_view strColumn = included::strColumn; -constexpr std::string_view strPath = included::strPath; -constexpr std::string_view strQuery = included::strQuery; -constexpr std::string_view strMutation = included::strMutation; -constexpr std::string_view strSubscription = included::strSubscription; - -using included::ResolverContext; - -using included::await_worker_thread; -using included::await_worker_queue; -using included::await_async; - -using included::Directives; -using included::FragmentDefinitionDirectiveStack; -using included::FragmentSpreadDirectiveStack; - -using included::SelectionSetParams; -using included::FieldParams; - -using included::AwaitableScalar; -using included::AwaitableObject; - -using included::Fragment; -using included::FragmentMap; - -using included::ResolverParams; -using included::ResolverResult; -using included::AwaitableResolver; -using included::Resolver; -using included::ResolverMap; - -using included::TypeModifier; -using included::Argument; - -using included::ModifiedArgument; -using included::IntArgument; -using included::FloatArgument; -using included::StringArgument; -using included::BooleanArgument; -using included::IdArgument; -using included::ScalarArgument; - -using included::TypeNames; -using included::Object; -using included::Result; - -using included::ModifiedResult; -using included::IntResult; -using included::FloatResult; -using included::StringResult; -using included::BooleanResult; -using included::IdResult; -using included::ScalarResult; -using included::ObjectResult; - -using included::SubscriptionCallback; -using included::SubscriptionKey; -using included::SubscriptionName; - -using included::AwaitableSubscribe; -using included::AwaitableUnsubscribe; -using included::AwaitableDeliver; - -using included::RequestResolveParams; -using included::RequestSubscribeParams; -using included::RequestUnsubscribeParams; - -using included::SubscriptionArguments; -using included::SubscriptionArgumentFilterCallback; -using included::SubscriptionDirectiveFilterCallback; -using included::SubscriptionFilter; - -using included::RequestDeliverFilter; -using included::RequestDeliverParams; - -using included::TypeMap; -using included::OperationData; -using included::SubscriptionData; - -using included::SubscriptionPlaceholder; - -using included::Request; -// clang-format on +using service::schema_location; +using service::path_segment; +using service::field_path; + +using service::error_path; +using service::buildErrorPath; -} // namespace exported +using service::schema_error; +using service::buildErrorValues; + +using service::schema_exception; +using service::unimplemented_method; + +using service::RequestState; + +namespace constants { + +constexpr std::string_view strData = service::strData; +constexpr std::string_view strErrors = service::strErrors; +constexpr std::string_view strMessage = service::strMessage; +constexpr std::string_view strLocations = service::strLocations; +constexpr std::string_view strLine = service::strLine; +constexpr std::string_view strColumn = service::strColumn; +constexpr std::string_view strPath = service::strPath; +constexpr std::string_view strQuery = service::strQuery; +constexpr std::string_view strMutation = service::strMutation; +constexpr std::string_view strSubscription = service::strSubscription; + +} // namespace constants + +using namespace constants; + +using service::ResolverContext; + +using service::await_worker_thread; +using service::await_worker_queue; +using service::await_async; + +using service::Directives; +using service::FragmentDefinitionDirectiveStack; +using service::FragmentSpreadDirectiveStack; + +using service::SelectionSetParams; +using service::FieldParams; + +using service::AwaitableScalar; +using service::AwaitableObject; + +using service::Fragment; +using service::FragmentMap; + +using service::ResolverParams; +using service::ResolverResult; +using service::AwaitableResolver; +using service::Resolver; +using service::ResolverMap; + +using service::TypeModifier; +using service::Argument; + +using service::ModifiedArgument; +using service::IntArgument; +using service::FloatArgument; +using service::StringArgument; +using service::BooleanArgument; +using service::IdArgument; +using service::ScalarArgument; + +using service::TypeNames; +using service::Object; +using service::Result; + +using service::ModifiedResult; +using service::IntResult; +using service::FloatResult; +using service::StringResult; +using service::BooleanResult; +using service::IdResult; +using service::ScalarResult; +using service::ObjectResult; + +using service::SubscriptionCallback; +using service::SubscriptionKey; +using service::SubscriptionName; + +using service::AwaitableSubscribe; +using service::AwaitableUnsubscribe; +using service::AwaitableDeliver; + +using service::RequestResolveParams; +using service::RequestSubscribeParams; +using service::RequestUnsubscribeParams; + +using service::SubscriptionArguments; +using service::SubscriptionArgumentFilterCallback; +using service::SubscriptionDirectiveFilterCallback; +using service::SubscriptionFilter; + +using service::RequestDeliverFilter; +using service::RequestDeliverParams; + +using service::TypeMap; +using service::OperationData; +using service::SubscriptionData; + +using service::SubscriptionPlaceholder; -using namespace exported; +using service::Request; +// clang-format on } // namespace service diff --git a/include/graphqlservice/internal/Awaitable.ixx b/include/graphqlservice/internal/Awaitable.ixx index c0ff337b..40d5e4c2 100644 --- a/include/graphqlservice/internal/Awaitable.ixx +++ b/include/graphqlservice/internal/Awaitable.ixx @@ -7,18 +7,10 @@ module; export module GraphQL.Internal.Awaitable; -namespace included = graphql::internal; - export namespace graphql::internal { -namespace exported { - // clang-format off -using included::Awaitable; +using internal::Awaitable; // clang-format on -} // namespace exported - -using namespace exported; - } // namespace graphql::internal diff --git a/include/graphqlservice/internal/Base64.ixx b/include/graphqlservice/internal/Base64.ixx index 5b1b9ecc..1952d46a 100644 --- a/include/graphqlservice/internal/Base64.ixx +++ b/include/graphqlservice/internal/Base64.ixx @@ -7,18 +7,10 @@ module; export module GraphQL.Internal.Base64; -namespace included = graphql::internal; - export namespace graphql::internal { -namespace exported { - // clang-format off -using included::Base64; +using internal::Base64; // clang-format on -} // namespace exported - -using namespace exported; - } // namespace graphql::internal diff --git a/include/graphqlservice/internal/Grammar.ixx b/include/graphqlservice/internal/Grammar.ixx index 66c655a3..2c780476 100644 --- a/include/graphqlservice/internal/Grammar.ixx +++ b/include/graphqlservice/internal/Grammar.ixx @@ -7,258 +7,250 @@ module; export module GraphQL.Internal.Grammar; -namespace included = graphql::peg; - export namespace graphql::peg { -namespace exported { - // clang-format off using namespace tao::graphqlpeg; -using included::for_each_child; -using included::on_first_child; -using included::on_first_child_if; +using peg::for_each_child; +using peg::on_first_child; +using peg::on_first_child_if; -using included::alias; -using included::alias_name; -using included::argument; -using included::argument_content; -using included::argument_name; -using included::arguments; -using included::arguments_content; -using included::backslash_token; -using included::block_escape_sequence; -using included::block_quote; -using included::block_quote_character; -using included::block_quote_content; -using included::block_quote_content_lines; -using included::block_quote_empty_line; -using included::block_quote_line; -using included::block_quote_line_content; -using included::block_quote_token; -using included::bool_value; -using included::comment; -using included::default_value; -using included::default_value_content; -using included::directive; -using included::directive_content; -using included::directive_name; -using included::directives; -using included::enum_value; -using included::escaped_char; -using included::escaped_unicode; -using included::escaped_unicode_codepoint; -using included::escaped_unicode_content; -using included::exponent_indicator; -using included::exponent_part; -using included::exponent_part_content; -using included::false_keyword; -using included::field; -using included::field_arguments; -using included::field_content; -using included::field_directives; -using included::field_name; -using included::field_selection_set; -using included::field_start; -using included::float_value; -using included::fractional_part; -using included::fractional_part_content; -using included::fragment_name; -using included::fragment_spread; -using included::fragment_token; -using included::ignored; -using included::inline_fragment; -using included::input_value; -using included::input_value_content; -using included::integer_part; -using included::integer_value; -using included::list_entry; -using included::list_type; -using included::list_type_content; -using included::list_value; -using included::list_value_content; -using included::name; -using included::named_type; -using included::negative_sign; -using included::nonnull_type; -using included::nonzero_digit; -using included::null_keyword; -using included::object_field; -using included::object_field_content; -using included::object_field_name; -using included::object_value; -using included::object_value_content; -using included::on_keyword; -using included::operation_type; -using included::quote_token; -using included::sign; -using included::source_character; -using included::string_escape_sequence; -using included::string_escape_sequence_content; -using included::string_quote; -using included::string_quote_character; -using included::string_quote_content; -using included::string_value; -using included::true_keyword; -using included::type_condition; -using included::type_condition_content; -using included::type_name; -using included::type_name_content; -using included::variable; -using included::variable_content; -using included::variable_definitions; -using included::variable_definitions_content; -using included::variable_name; -using included::variable_name_content; -using included::variable_value; -using included::zero_digit; -using included::fragement_spread_or_inline_fragment_content; -using included::fragement_spread_or_inline_fragment; -using included::operation_name; -using included::selection; -using included::selection_set; -using included::selection_set_content; -using included::operation_definition_operation_type_content; -using included::arguments_definition; -using included::arguments_definition_content; -using included::arguments_definition_start; -using included::description; -using included::executable_definition; -using included::field_definition; -using included::field_definition_content; -using included::field_definition_start; -using included::fields_definition; -using included::fields_definition_content; -using included::fragment_definition; -using included::fragment_definition_content; -using included::implements_interfaces; -using included::implements_interfaces_content; -using included::interface_type; -using included::object_name; -using included::object_type_definition_object_name; -using included::object_type_definition_start; -using included::operation_definition; -using included::root_operation_definition; -using included::root_operation_definition_content; -using included::scalar_keyword; -using included::scalar_name; -using included::scalar_type_definition; -using included::scalar_type_definition_content; -using included::scalar_type_definition_start; -using included::schema_definition; -using included::schema_definition_content; -using included::schema_definition_start; -using included::schema_keyword; -using included::type_keyword; -using included::object_type_definition_implements_interfaces; -using included::interface_keyword; -using included::interface_name; -using included::interface_type_definition_interface_name; -using included::interface_type_definition_start; -using included::object_type_definition; -using included::object_type_definition_content; -using included::object_type_definition_directives; -using included::object_type_definition_fields_definition; -using included::interface_type_definition_implements_interfaces; -using included::interface_type_definition_directives; -using included::interface_type_definition_fields_definition; -using included::enum_keyword; -using included::enum_name; -using included::enum_type_definition_directives; -using included::enum_type_definition_name; -using included::enum_type_definition_start; -using included::enum_value_definition; -using included::enum_value_definition_content; -using included::enum_value_definition_start; -using included::enum_values_definition; -using included::enum_values_definition_content; -using included::enum_values_definition_start; -using included::interface_type_definition; -using included::interface_type_definition_content; -using included::union_keyword; -using included::union_member_types; -using included::union_member_types_content; -using included::union_member_types_start; -using included::union_name; -using included::union_type; -using included::union_type_definition; -using included::union_type_definition_content; -using included::union_type_definition_directives; -using included::union_type_definition_start; -using included::enum_type_definition_enum_values_definition; -using included::enum_type_definition; -using included::enum_type_definition_content; -using included::input_field_definition; -using included::input_field_definition_content; -using included::input_field_definition_default_value; -using included::input_field_definition_directives; -using included::input_field_definition_start; -using included::input_field_definition_type_name; -using included::input_fields_definition; -using included::input_fields_definition_content; -using included::input_fields_definition_start; -using included::input_keyword; -using included::input_object_type_definition_directives; -using included::input_object_type_definition_object_name; -using included::input_object_type_definition_start; -using included::input_object_type_definition_fields_definition; -using included::directive_definition; -using included::directive_definition_content; -using included::directive_definition_start; -using included::directive_location; -using included::directive_locations; -using included::executable_directive_location; -using included::extend_keyword; -using included::input_object_type_definition; -using included::input_object_type_definition_content; -using included::operation_type_definition; -using included::repeatable_keyword; -using included::schema_extension_start; -using included::type_definition; -using included::type_system_definition; -using included::type_system_directive_location; -using included::schema_extension_operation_type_definitions; -using included::object_type_extension_start; -using included::scalar_type_extension; -using included::scalar_type_extension_content; -using included::scalar_type_extension_start; -using included::schema_extension; -using included::schema_extension_content; -using included::object_type_extension_implements_interfaces; -using included::interface_type_extension_start; -using included::object_type_extension; -using included::object_type_extension_content; -using included::object_type_extension_directives; -using included::object_type_extension_fields_definition; -using included::interface_type_extension_implements_interfaces; -using included::interface_type_extension_directives; -using included::interface_type_extension_fields_definition; -using included::enum_type_extension; -using included::enum_type_extension_content; -using included::enum_type_extension_start; -using included::executable_document; -using included::executable_document_content; -using included::input_object_type_extension; -using included::input_object_type_extension_content; -using included::input_object_type_extension_start; -using included::interface_type_extension; -using included::interface_type_extension_content; -using included::mixed_definition; -using included::mixed_document; -using included::mixed_document_content; -using included::schema_document; -using included::schema_document_content; -using included::schema_type_definition; -using included::type_extension; -using included::type_system_extension; -using included::union_type_extension; -using included::union_type_extension_content; -using included::union_type_extension_start; +using peg::alias; +using peg::alias_name; +using peg::argument; +using peg::argument_content; +using peg::argument_name; +using peg::arguments; +using peg::arguments_content; +using peg::backslash_token; +using peg::block_escape_sequence; +using peg::block_quote; +using peg::block_quote_character; +using peg::block_quote_content; +using peg::block_quote_content_lines; +using peg::block_quote_empty_line; +using peg::block_quote_line; +using peg::block_quote_line_content; +using peg::block_quote_token; +using peg::bool_value; +using peg::comment; +using peg::default_value; +using peg::default_value_content; +using peg::directive; +using peg::directive_content; +using peg::directive_name; +using peg::directives; +using peg::enum_value; +using peg::escaped_char; +using peg::escaped_unicode; +using peg::escaped_unicode_codepoint; +using peg::escaped_unicode_content; +using peg::exponent_indicator; +using peg::exponent_part; +using peg::exponent_part_content; +using peg::false_keyword; +using peg::field; +using peg::field_arguments; +using peg::field_content; +using peg::field_directives; +using peg::field_name; +using peg::field_selection_set; +using peg::field_start; +using peg::float_value; +using peg::fractional_part; +using peg::fractional_part_content; +using peg::fragment_name; +using peg::fragment_spread; +using peg::fragment_token; +using peg::ignored; +using peg::inline_fragment; +using peg::input_value; +using peg::input_value_content; +using peg::integer_part; +using peg::integer_value; +using peg::list_entry; +using peg::list_type; +using peg::list_type_content; +using peg::list_value; +using peg::list_value_content; +using peg::name; +using peg::named_type; +using peg::negative_sign; +using peg::nonnull_type; +using peg::nonzero_digit; +using peg::null_keyword; +using peg::object_field; +using peg::object_field_content; +using peg::object_field_name; +using peg::object_value; +using peg::object_value_content; +using peg::on_keyword; +using peg::operation_type; +using peg::quote_token; +using peg::sign; +using peg::source_character; +using peg::string_escape_sequence; +using peg::string_escape_sequence_content; +using peg::string_quote; +using peg::string_quote_character; +using peg::string_quote_content; +using peg::string_value; +using peg::true_keyword; +using peg::type_condition; +using peg::type_condition_content; +using peg::type_name; +using peg::type_name_content; +using peg::variable; +using peg::variable_content; +using peg::variable_definitions; +using peg::variable_definitions_content; +using peg::variable_name; +using peg::variable_name_content; +using peg::variable_value; +using peg::zero_digit; +using peg::fragement_spread_or_inline_fragment_content; +using peg::fragement_spread_or_inline_fragment; +using peg::operation_name; +using peg::selection; +using peg::selection_set; +using peg::selection_set_content; +using peg::operation_definition_operation_type_content; +using peg::arguments_definition; +using peg::arguments_definition_content; +using peg::arguments_definition_start; +using peg::description; +using peg::executable_definition; +using peg::field_definition; +using peg::field_definition_content; +using peg::field_definition_start; +using peg::fields_definition; +using peg::fields_definition_content; +using peg::fragment_definition; +using peg::fragment_definition_content; +using peg::implements_interfaces; +using peg::implements_interfaces_content; +using peg::interface_type; +using peg::object_name; +using peg::object_type_definition_object_name; +using peg::object_type_definition_start; +using peg::operation_definition; +using peg::root_operation_definition; +using peg::root_operation_definition_content; +using peg::scalar_keyword; +using peg::scalar_name; +using peg::scalar_type_definition; +using peg::scalar_type_definition_content; +using peg::scalar_type_definition_start; +using peg::schema_definition; +using peg::schema_definition_content; +using peg::schema_definition_start; +using peg::schema_keyword; +using peg::type_keyword; +using peg::object_type_definition_implements_interfaces; +using peg::interface_keyword; +using peg::interface_name; +using peg::interface_type_definition_interface_name; +using peg::interface_type_definition_start; +using peg::object_type_definition; +using peg::object_type_definition_content; +using peg::object_type_definition_directives; +using peg::object_type_definition_fields_definition; +using peg::interface_type_definition_implements_interfaces; +using peg::interface_type_definition_directives; +using peg::interface_type_definition_fields_definition; +using peg::enum_keyword; +using peg::enum_name; +using peg::enum_type_definition_directives; +using peg::enum_type_definition_name; +using peg::enum_type_definition_start; +using peg::enum_value_definition; +using peg::enum_value_definition_content; +using peg::enum_value_definition_start; +using peg::enum_values_definition; +using peg::enum_values_definition_content; +using peg::enum_values_definition_start; +using peg::interface_type_definition; +using peg::interface_type_definition_content; +using peg::union_keyword; +using peg::union_member_types; +using peg::union_member_types_content; +using peg::union_member_types_start; +using peg::union_name; +using peg::union_type; +using peg::union_type_definition; +using peg::union_type_definition_content; +using peg::union_type_definition_directives; +using peg::union_type_definition_start; +using peg::enum_type_definition_enum_values_definition; +using peg::enum_type_definition; +using peg::enum_type_definition_content; +using peg::input_field_definition; +using peg::input_field_definition_content; +using peg::input_field_definition_default_value; +using peg::input_field_definition_directives; +using peg::input_field_definition_start; +using peg::input_field_definition_type_name; +using peg::input_fields_definition; +using peg::input_fields_definition_content; +using peg::input_fields_definition_start; +using peg::input_keyword; +using peg::input_object_type_definition_directives; +using peg::input_object_type_definition_object_name; +using peg::input_object_type_definition_start; +using peg::input_object_type_definition_fields_definition; +using peg::directive_definition; +using peg::directive_definition_content; +using peg::directive_definition_start; +using peg::directive_location; +using peg::directive_locations; +using peg::executable_directive_location; +using peg::extend_keyword; +using peg::input_object_type_definition; +using peg::input_object_type_definition_content; +using peg::operation_type_definition; +using peg::repeatable_keyword; +using peg::schema_extension_start; +using peg::type_definition; +using peg::type_system_definition; +using peg::type_system_directive_location; +using peg::schema_extension_operation_type_definitions; +using peg::object_type_extension_start; +using peg::scalar_type_extension; +using peg::scalar_type_extension_content; +using peg::scalar_type_extension_start; +using peg::schema_extension; +using peg::schema_extension_content; +using peg::object_type_extension_implements_interfaces; +using peg::interface_type_extension_start; +using peg::object_type_extension; +using peg::object_type_extension_content; +using peg::object_type_extension_directives; +using peg::object_type_extension_fields_definition; +using peg::interface_type_extension_implements_interfaces; +using peg::interface_type_extension_directives; +using peg::interface_type_extension_fields_definition; +using peg::enum_type_extension; +using peg::enum_type_extension_content; +using peg::enum_type_extension_start; +using peg::executable_document; +using peg::executable_document_content; +using peg::input_object_type_extension; +using peg::input_object_type_extension_content; +using peg::input_object_type_extension_start; +using peg::interface_type_extension; +using peg::interface_type_extension_content; +using peg::mixed_definition; +using peg::mixed_document; +using peg::mixed_document_content; +using peg::schema_document; +using peg::schema_document_content; +using peg::schema_type_definition; +using peg::type_extension; +using peg::type_system_extension; +using peg::union_type_extension; +using peg::union_type_extension_content; +using peg::union_type_extension_start; // clang-format on -} // namespace exported - -using namespace exported; - } // namespace graphql::peg diff --git a/include/graphqlservice/internal/Introspection.ixx b/include/graphqlservice/internal/Introspection.ixx index f46c54c6..3dab858d 100644 --- a/include/graphqlservice/internal/Introspection.ixx +++ b/include/graphqlservice/internal/Introspection.ixx @@ -7,23 +7,15 @@ module; export module GraphQL.Internal.Introspection; -namespace included = graphql::introspection; - export namespace graphql::introspection { -namespace exported { - // clang-format off -using included::Schema; -using included::Type; -using included::Field; -using included::InputValue; -using included::EnumValue; -using included::Directive; +using introspection::Schema; +using introspection::Type; +using introspection::Field; +using introspection::InputValue; +using introspection::EnumValue; +using introspection::Directive; // clang-format on -} // namespace exported - -using namespace exported; - } // namespace graphql::introspection diff --git a/include/graphqlservice/internal/Schema.ixx b/include/graphqlservice/internal/Schema.ixx index fd058694..19cf2ff3 100644 --- a/include/graphqlservice/internal/Schema.ixx +++ b/include/graphqlservice/internal/Schema.ixx @@ -7,55 +7,36 @@ module; export module GraphQL.Internal.Schema; -namespace included { - -namespace introspection = graphql::introspection; -namespace schema = graphql::schema; - -} // namespace included - export namespace graphql { namespace introspection { -namespace exported { - // clang-format off -using included::introspection::TypeKind; -using included::introspection::DirectiveLocation; +using introspection::TypeKind; +using introspection::DirectiveLocation; // clang-format on -} // namespace exported - -using namespace exported; - } // namespace introspection namespace schema { -namespace exported { - // clang-format off -using included::schema::Schema; -using included::schema::BaseType; -using included::schema::ScalarType; -using included::schema::ObjectType; -using included::schema::InterfaceType; -using included::schema::UnionType; -using included::schema::EnumValueType; -using included::schema::EnumType; -using included::schema::InputObjectType; -using included::schema::WrapperType; -using included::schema::Field; -using included::schema::InputValue; -using included::schema::EnumValue; -using included::schema::Directive; +using schema::Schema; +using schema::BaseType; +using schema::ScalarType; +using schema::ObjectType; +using schema::InterfaceType; +using schema::UnionType; +using schema::EnumValueType; +using schema::EnumType; +using schema::InputObjectType; +using schema::WrapperType; +using schema::Field; +using schema::InputValue; +using schema::EnumValue; +using schema::Directive; // clang-format on -} // namespace exported - -using namespace exported; - } // namespace schema } // namespace graphql diff --git a/include/graphqlservice/internal/SortedMap.ixx b/include/graphqlservice/internal/SortedMap.ixx index 18415848..156dd864 100644 --- a/include/graphqlservice/internal/SortedMap.ixx +++ b/include/graphqlservice/internal/SortedMap.ixx @@ -7,25 +7,17 @@ module; export module GraphQL.Internal.SortedMap; -namespace included = graphql::internal; - export namespace graphql::internal { -namespace exported { - // clang-format off -using included::sorted_map_key; -using included::sorted_map_equal_range; -using included::sorted_map_lookup; -using included::sorted_map; -using included::sorted_set; -using included::shorter_or_less; -using included::string_view_map; -using included::string_view_set; +using internal::sorted_map_key; +using internal::sorted_map_equal_range; +using internal::sorted_map_lookup; +using internal::sorted_map; +using internal::sorted_set; +using internal::shorter_or_less; +using internal::string_view_map; +using internal::string_view_set; // clang-format on -} // namespace exported - -using namespace exported; - } // namespace graphql::internal diff --git a/include/graphqlservice/internal/SyntaxTree.ixx b/include/graphqlservice/internal/SyntaxTree.ixx index 67c3134b..1fe4f213 100644 --- a/include/graphqlservice/internal/SyntaxTree.ixx +++ b/include/graphqlservice/internal/SyntaxTree.ixx @@ -9,17 +9,11 @@ export module GraphQL.Internal.SyntaxTree; export namespace graphql::peg { -namespace exported { - // clang-format off using namespace tao::graphqlpeg; namespace peginternal = tao::graphqlpeg::internal; -using graphql::peg::ast_node; +using peg::ast_node; // clang-format on -} // namespace exported - -using namespace exported; - } // namespace graphql::peg diff --git a/include/graphqlservice/internal/Version.ixx b/include/graphqlservice/internal/Version.ixx index 86bf0cd5..a763b98c 100644 --- a/include/graphqlservice/internal/Version.ixx +++ b/include/graphqlservice/internal/Version.ixx @@ -9,15 +9,16 @@ export module GraphQL.Internal.Version; export namespace graphql::internal { -namespace version { +namespace constants { -constexpr std::string_view FullVersion = graphql::internal::FullVersion; -constexpr std::size_t MajorVersion = graphql::internal::MajorVersion; -constexpr std::size_t MinorVersion = graphql::internal::MinorVersion; -constexpr std::size_t PatchVersion = graphql::internal::PatchVersion; +constexpr std::string_view FullVersion = internal::FullVersion; -} // namespace version +constexpr std::size_t MajorVersion = internal::MajorVersion; +constexpr std::size_t MinorVersion = internal::MinorVersion; +constexpr std::size_t PatchVersion = internal::PatchVersion; -using namespace version; +} // namespace constants + +using namespace constants; } // namespace graphql::internal diff --git a/include/graphqlservice/introspection/DirectiveObject.ixx b/include/graphqlservice/introspection/DirectiveObject.ixx index 97f3dae7..8a00c78d 100644 --- a/include/graphqlservice/introspection/DirectiveObject.ixx +++ b/include/graphqlservice/introspection/DirectiveObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.DirectiveObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::Directive; - -} // namespace exported - -using namespace exported; +using object::Directive; } // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/EnumValueObject.ixx b/include/graphqlservice/introspection/EnumValueObject.ixx index 572acd70..45be5d13 100644 --- a/include/graphqlservice/introspection/EnumValueObject.ixx +++ b/include/graphqlservice/introspection/EnumValueObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.EnumValueObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::EnumValue; - -} // namespace exported - -using namespace exported; +using object::EnumValue; } // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/FieldObject.ixx b/include/graphqlservice/introspection/FieldObject.ixx index b98ed284..aa5c8305 100644 --- a/include/graphqlservice/introspection/FieldObject.ixx +++ b/include/graphqlservice/introspection/FieldObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.FieldObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::Field; - -} // namespace exported - -using namespace exported; +using object::Field; } // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/InputValueObject.ixx b/include/graphqlservice/introspection/InputValueObject.ixx index b3ca2cfd..252760df 100644 --- a/include/graphqlservice/introspection/InputValueObject.ixx +++ b/include/graphqlservice/introspection/InputValueObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.InputValueObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::InputValue; - -} // namespace exported - -using namespace exported; +using object::InputValue; } // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/IntrospectionSchema.ixx b/include/graphqlservice/introspection/IntrospectionSchema.ixx index 77d96507..2044667f 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.ixx +++ b/include/graphqlservice/introspection/IntrospectionSchema.ixx @@ -13,27 +13,21 @@ namespace included = graphql::introspection; export namespace graphql::introspection { -namespace exported { - -using included::TypeKind; -using included::getTypeKindNames; -using included::getTypeKindValues; - -using included::DirectiveLocation; -using included::getDirectiveLocationNames; -using included::getDirectiveLocationValues; - -using included::AddSchemaDetails; -using included::AddTypeDetails; -using included::AddFieldDetails; -using included::AddInputValueDetails; -using included::AddEnumValueDetails; -using included::AddDirectiveDetails; - -using included::AddTypesToSchema; - -} // namespace exported - -using namespace exported; +using introspection::TypeKind; +using introspection::getTypeKindNames; +using introspection::getTypeKindValues; + +using introspection::DirectiveLocation; +using introspection::getDirectiveLocationNames; +using introspection::getDirectiveLocationValues; + +using introspection::AddSchemaDetails; +using introspection::AddTypeDetails; +using introspection::AddFieldDetails; +using introspection::AddInputValueDetails; +using introspection::AddEnumValueDetails; +using introspection::AddDirectiveDetails; + +using introspection::AddTypesToSchema; } // namespace graphql::introspection diff --git a/include/graphqlservice/introspection/SchemaObject.ixx b/include/graphqlservice/introspection/SchemaObject.ixx index 063cc3f7..56735d85 100644 --- a/include/graphqlservice/introspection/SchemaObject.ixx +++ b/include/graphqlservice/introspection/SchemaObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.SchemaObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::Schema; - -} // namespace exported - -using namespace exported; +using object::Schema; } // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/TypeObject.ixx b/include/graphqlservice/introspection/TypeObject.ixx index 401a9329..001ccdd6 100644 --- a/include/graphqlservice/introspection/TypeObject.ixx +++ b/include/graphqlservice/introspection/TypeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.TypeObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::Type; - -} // namespace exported - -using namespace exported; +using object::Type; } // namespace graphql::introspection::object diff --git a/samples/client/benchmark/BenchmarkClient.ixx b/samples/client/benchmark/BenchmarkClient.ixx index ab820a60..64b88c5b 100644 --- a/samples/client/benchmark/BenchmarkClient.ixx +++ b/samples/client/benchmark/BenchmarkClient.ixx @@ -9,34 +9,27 @@ module; export module GraphQL.Benchmark.BenchmarkClient; -namespace included = graphql::client; - export namespace graphql::client { -namespace exported { namespace benchmark { -using included::benchmark::GetRequestText; -using included::benchmark::GetRequestObject; +using benchmark::GetRequestText; +using benchmark::GetRequestObject; } // namespace benchmark namespace query::Query { -using included::benchmark::GetRequestText; -using included::benchmark::GetRequestObject; -using included::query::Query::GetOperationName; +using benchmark::GetRequestText; +using benchmark::GetRequestObject; +using Query::GetOperationName; -using included::query::Query::Response; -using included::query::Query::parseResponse; +using Query::Response; +using Query::parseResponse; -using included::query::Query::Traits; +using Query::Traits; } // namespace query::Query -} // namespace exported - -using namespace exported; - } // namespace graphql::client diff --git a/samples/client/multiple/MultipleQueriesClient.ixx b/samples/client/multiple/MultipleQueriesClient.ixx index b4ea36cf..f2b5ce2d 100644 --- a/samples/client/multiple/MultipleQueriesClient.ixx +++ b/samples/client/multiple/MultipleQueriesClient.ixx @@ -9,99 +9,92 @@ module; export module GraphQL.MultipleQueries.MultipleQueriesClient; -namespace included = graphql::client; - export namespace graphql::client { -namespace exported { namespace multiple { -using included::multiple::GetRequestText; -using included::multiple::GetRequestObject; +using multiple::GetRequestText; +using multiple::GetRequestObject; -using included::multiple::TaskState; +using multiple::TaskState; -using included::multiple::CompleteTaskInput; +using multiple::CompleteTaskInput; } // namespace multiple namespace query::Appointments { -using included::multiple::GetRequestText; -using included::multiple::GetRequestObject; -using included::query::Appointments::GetOperationName; +using multiple::GetRequestText; +using multiple::GetRequestObject; +using Appointments::GetOperationName; -using included::query::Appointments::Response; -using included::query::Appointments::parseResponse; +using Appointments::Response; +using Appointments::parseResponse; -using included::query::Appointments::Traits; +using Appointments::Traits; } // namespace query::Appointments namespace query::Tasks { -using included::multiple::GetRequestText; -using included::multiple::GetRequestObject; -using included::query::Tasks::GetOperationName; +using multiple::GetRequestText; +using multiple::GetRequestObject; +using Tasks::GetOperationName; -using included::query::Tasks::Response; -using included::query::Tasks::parseResponse; +using Tasks::Response; +using Tasks::parseResponse; -using included::query::Tasks::Traits; +using Tasks::Traits; } // namespace query::Tasks namespace query::UnreadCounts { -using included::multiple::GetRequestText; -using included::multiple::GetRequestObject; -using included::query::UnreadCounts::GetOperationName; +using multiple::GetRequestText; +using multiple::GetRequestObject; +using UnreadCounts::GetOperationName; -using included::query::UnreadCounts::Response; -using included::query::UnreadCounts::parseResponse; +using UnreadCounts::Response; +using UnreadCounts::parseResponse; -using included::query::UnreadCounts::Traits; +using UnreadCounts::Traits; } // namespace query::UnreadCounts namespace query::Miscellaneous { -using included::multiple::GetRequestText; -using included::multiple::GetRequestObject; -using included::query::Miscellaneous::GetOperationName; +using multiple::GetRequestText; +using multiple::GetRequestObject; +using Miscellaneous::GetOperationName; -using included::multiple::TaskState; +using multiple::TaskState; -using included::query::Miscellaneous::Response; -using included::query::Miscellaneous::parseResponse; +using Miscellaneous::Response; +using Miscellaneous::parseResponse; -using included::query::Miscellaneous::Traits; +using Miscellaneous::Traits; } // namespace query::Miscellaneous namespace mutation::CompleteTaskMutation { -using included::multiple::GetRequestText; -using included::multiple::GetRequestObject; -using included::mutation::CompleteTaskMutation::GetOperationName; +using multiple::GetRequestText; +using multiple::GetRequestObject; +using CompleteTaskMutation::GetOperationName; -using included::multiple::TaskState; +using multiple::TaskState; -using included::multiple::CompleteTaskInput; +using multiple::CompleteTaskInput; -using included::mutation::CompleteTaskMutation::Variables; -using included::mutation::CompleteTaskMutation::serializeVariables; +using CompleteTaskMutation::Variables; +using CompleteTaskMutation::serializeVariables; -using included::mutation::CompleteTaskMutation::Response; -using included::mutation::CompleteTaskMutation::parseResponse; +using CompleteTaskMutation::Response; +using CompleteTaskMutation::parseResponse; -using included::mutation::CompleteTaskMutation::Traits; +using CompleteTaskMutation::Traits; } // namespace mutation::CompleteTaskMutation -} // namespace exported - -using namespace exported; - } // namespace graphql::client diff --git a/samples/client/mutate/MutateClient.ixx b/samples/client/mutate/MutateClient.ixx index fe9c9592..9c4579ee 100644 --- a/samples/client/mutate/MutateClient.ixx +++ b/samples/client/mutate/MutateClient.ixx @@ -9,45 +9,38 @@ module; export module GraphQL.Mutate.MutateClient; -namespace included = graphql::client; - export namespace graphql::client { -namespace exported { namespace mutate { -using included::mutate::GetRequestText; -using included::mutate::GetRequestObject; +using mutate::GetRequestText; +using mutate::GetRequestObject; -using included::mutate::TaskState; +using mutate::TaskState; -using included::mutate::CompleteTaskInput; +using mutate::CompleteTaskInput; } // namespace mutate namespace mutation::CompleteTaskMutation { -using included::mutate::GetRequestText; -using included::mutate::GetRequestObject; -using included::mutation::CompleteTaskMutation::GetOperationName; +using mutate::GetRequestText; +using mutate::GetRequestObject; +using CompleteTaskMutation::GetOperationName; -using included::mutate::TaskState; +using mutate::TaskState; -using included::mutate::CompleteTaskInput; +using mutate::CompleteTaskInput; -using included::mutation::CompleteTaskMutation::Variables; -using included::mutation::CompleteTaskMutation::serializeVariables; +using CompleteTaskMutation::Variables; +using CompleteTaskMutation::serializeVariables; -using included::mutation::CompleteTaskMutation::Response; -using included::mutation::CompleteTaskMutation::parseResponse; +using CompleteTaskMutation::Response; +using CompleteTaskMutation::parseResponse; -using included::mutation::CompleteTaskMutation::Traits; +using CompleteTaskMutation::Traits; } // namespace mutation::CompleteTaskMutation -} // namespace exported - -using namespace exported; - } // namespace graphql::client diff --git a/samples/client/nestedinput/NestedInputClient.ixx b/samples/client/nestedinput/NestedInputClient.ixx index b64a60b6..fe02a9a8 100644 --- a/samples/client/nestedinput/NestedInputClient.ixx +++ b/samples/client/nestedinput/NestedInputClient.ixx @@ -9,47 +9,40 @@ module; export module GraphQL.NestedInput.NestedInputClient; -namespace included = graphql::client; - export namespace graphql::client { -namespace exported { namespace nestedinput { -using included::nestedinput::GetRequestText; -using included::nestedinput::GetRequestObject; +using nestedinput::GetRequestText; +using nestedinput::GetRequestObject; -using included::nestedinput::InputA; -using included::nestedinput::InputB; -using included::nestedinput::InputABCD; -using included::nestedinput::InputBC; +using nestedinput::InputA; +using nestedinput::InputB; +using nestedinput::InputABCD; +using nestedinput::InputBC; } // namespace nestedinput namespace query::testQuery { -using included::nestedinput::GetRequestText; -using included::nestedinput::GetRequestObject; -using included::query::testQuery::GetOperationName; +using nestedinput::GetRequestText; +using nestedinput::GetRequestObject; +using testQuery::GetOperationName; -using included::nestedinput::InputA; -using included::nestedinput::InputB; -using included::nestedinput::InputABCD; -using included::nestedinput::InputBC; +using nestedinput::InputA; +using nestedinput::InputB; +using nestedinput::InputABCD; +using nestedinput::InputBC; -using included::query::testQuery::Variables; -using included::query::testQuery::serializeVariables; +using testQuery::Variables; +using testQuery::serializeVariables; -using included::query::testQuery::Response; -using included::query::testQuery::parseResponse; +using testQuery::Response; +using testQuery::parseResponse; -using included::query::testQuery::Traits; +using testQuery::Traits; } // namespace query::testQuery -} // namespace exported - -using namespace exported; - } // namespace graphql::client diff --git a/samples/client/query/QueryClient.ixx b/samples/client/query/QueryClient.ixx index f765e94a..f4d077ef 100644 --- a/samples/client/query/QueryClient.ixx +++ b/samples/client/query/QueryClient.ixx @@ -9,38 +9,31 @@ module; export module GraphQL.Query.QueryClient; -namespace included = graphql::client; - export namespace graphql::client { -namespace exported { namespace query { -using included::query::GetRequestText; -using included::query::GetRequestObject; +using query::GetRequestText; +using query::GetRequestObject; -using included::query::TaskState; +using query::TaskState; } // namespace query namespace query::Query { -using included::query::GetRequestText; -using included::query::GetRequestObject; -using included::query::Query::GetOperationName; +using query::GetRequestText; +using query::GetRequestObject; +using Query::GetOperationName; -using included::query::TaskState; +using query::TaskState; -using included::query::Query::Response; -using included::query::Query::parseResponse; +using Query::Response; +using Query::parseResponse; -using included::query::Query::Traits; +using Query::Traits; } // namespace query::Query -} // namespace exported - -using namespace exported; - } // namespace graphql::client diff --git a/samples/client/subscribe/SubscribeClient.ixx b/samples/client/subscribe/SubscribeClient.ixx index aeadc3a3..adeae8ed 100644 --- a/samples/client/subscribe/SubscribeClient.ixx +++ b/samples/client/subscribe/SubscribeClient.ixx @@ -9,34 +9,27 @@ module; export module GraphQL.Subscribe.SubscribeClient; -namespace included = graphql::client; - export namespace graphql::client { -namespace exported { namespace subscribe { -using included::subscribe::GetRequestText; -using included::subscribe::GetRequestObject; +using subscribe::GetRequestText; +using subscribe::GetRequestObject; } // namespace subscribe namespace subscription::TestSubscription { -using included::subscribe::GetRequestText; -using included::subscribe::GetRequestObject; -using included::subscription::TestSubscription::GetOperationName; +using subscribe::GetRequestText; +using subscribe::GetRequestObject; +using TestSubscription::GetOperationName; -using included::subscription::TestSubscription::Response; -using included::subscription::TestSubscription::parseResponse; +using TestSubscription::Response; +using TestSubscription::parseResponse; -using included::subscription::TestSubscription::Traits; +using TestSubscription::Traits; } // namespace subscription::TestSubscription -} // namespace exported - -using namespace exported; - } // namespace graphql::client diff --git a/samples/learn/schema/CharacterObject.ixx b/samples/learn/schema/CharacterObject.ixx index eb23c6f2..9917b823 100644 --- a/samples/learn/schema/CharacterObject.ixx +++ b/samples/learn/schema/CharacterObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.StarWars.CharacterObject; -namespace included = graphql::learn::object; - export namespace graphql::learn::object { -namespace exported { - -using included::Character; - -} // namespace exported - -using namespace exported; +using object::Character; } // namespace graphql::learn::object diff --git a/samples/learn/schema/DroidObject.ixx b/samples/learn/schema/DroidObject.ixx index 795b4232..166edcc7 100644 --- a/samples/learn/schema/DroidObject.ixx +++ b/samples/learn/schema/DroidObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.StarWars.DroidObject; -namespace included = graphql::learn::object; - export namespace graphql::learn::object { -namespace exported { - -using included::Droid; - -} // namespace exported - -using namespace exported; +using object::Droid; } // namespace graphql::learn::object diff --git a/samples/learn/schema/HumanObject.ixx b/samples/learn/schema/HumanObject.ixx index 07db6b5b..9a218221 100644 --- a/samples/learn/schema/HumanObject.ixx +++ b/samples/learn/schema/HumanObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.StarWars.HumanObject; -namespace included = graphql::learn::object; - export namespace graphql::learn::object { -namespace exported { - -using included::Human; - -} // namespace exported - -using namespace exported; +using object::Human; } // namespace graphql::learn::object diff --git a/samples/learn/schema/MutationObject.ixx b/samples/learn/schema/MutationObject.ixx index 4e233adf..1a2b2cba 100644 --- a/samples/learn/schema/MutationObject.ixx +++ b/samples/learn/schema/MutationObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.StarWars.MutationObject; -namespace included = graphql::learn::object; - export namespace graphql::learn::object { -namespace exported { - -using included::Mutation; - -} // namespace exported - -using namespace exported; +using object::Mutation; } // namespace graphql::learn::object diff --git a/samples/learn/schema/QueryObject.ixx b/samples/learn/schema/QueryObject.ixx index de1e3865..dfe464c1 100644 --- a/samples/learn/schema/QueryObject.ixx +++ b/samples/learn/schema/QueryObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.StarWars.QueryObject; -namespace included = graphql::learn::object; - export namespace graphql::learn::object { -namespace exported { - -using included::Query; - -} // namespace exported - -using namespace exported; +using object::Query; } // namespace graphql::learn::object diff --git a/samples/learn/schema/ReviewObject.ixx b/samples/learn/schema/ReviewObject.ixx index 492a843f..067321d1 100644 --- a/samples/learn/schema/ReviewObject.ixx +++ b/samples/learn/schema/ReviewObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.StarWars.ReviewObject; -namespace included = graphql::learn::object; - export namespace graphql::learn::object { -namespace exported { - -using included::Review; - -} // namespace exported - -using namespace exported; +using object::Review; } // namespace graphql::learn::object diff --git a/samples/learn/schema/StarWarsSchema.ixx b/samples/learn/schema/StarWarsSchema.ixx index b0a8eb89..64ef57b0 100644 --- a/samples/learn/schema/StarWarsSchema.ixx +++ b/samples/learn/schema/StarWarsSchema.ixx @@ -13,27 +13,21 @@ namespace included = graphql::learn; export namespace graphql::learn { -namespace exported { +using learn::Episode; +using learn::getEpisodeNames; +using learn::getEpisodeValues; -using included::Episode; -using included::getEpisodeNames; -using included::getEpisodeValues; +using learn::ReviewInput; -using included::ReviewInput; +using learn::Operations; -using included::Operations; +using learn::AddCharacterDetails; +using learn::AddHumanDetails; +using learn::AddDroidDetails; +using learn::AddQueryDetails; +using learn::AddReviewDetails; +using learn::AddMutationDetails; -using included::AddCharacterDetails; -using included::AddHumanDetails; -using included::AddDroidDetails; -using included::AddQueryDetails; -using included::AddReviewDetails; -using included::AddMutationDetails; - -using included::GetSchema; - -} // namespace exported - -using namespace exported; +using learn::GetSchema; } // namespace graphql::learn diff --git a/samples/proxy/query/ProxyClient.ixx b/samples/proxy/query/ProxyClient.ixx index 39f8167a..65b38f32 100644 --- a/samples/proxy/query/ProxyClient.ixx +++ b/samples/proxy/query/ProxyClient.ixx @@ -9,37 +9,30 @@ module; export module GraphQL.Proxy.ProxyClient; -namespace included = graphql::client; - export namespace graphql::client { -namespace exported { namespace proxy { -using included::proxy::GetRequestText; -using included::proxy::GetRequestObject; +using proxy::GetRequestText; +using proxy::GetRequestObject; } // namespace proxy namespace query::relayQuery { -using included::proxy::GetRequestText; -using included::proxy::GetRequestObject; -using included::query::relayQuery::GetOperationName; +using proxy::GetRequestText; +using proxy::GetRequestObject; +using relayQuery::GetOperationName; -using included::query::relayQuery::Variables; -using included::query::relayQuery::serializeVariables; +using relayQuery::Variables; +using relayQuery::serializeVariables; -using included::query::relayQuery::Response; -using included::query::relayQuery::parseResponse; +using relayQuery::Response; +using relayQuery::parseResponse; -using included::query::relayQuery::Traits; +using relayQuery::Traits; } // namespace query::relayQuery -} // namespace exported - -using namespace exported; - } // namespace graphql::client diff --git a/samples/proxy/schema/ProxySchema.ixx b/samples/proxy/schema/ProxySchema.ixx index 98a36d37..a8d801b7 100644 --- a/samples/proxy/schema/ProxySchema.ixx +++ b/samples/proxy/schema/ProxySchema.ixx @@ -13,16 +13,10 @@ namespace included = graphql::proxy; export namespace graphql::proxy { -namespace exported { +using proxy::Operations; -using included::Operations; +using proxy::AddQueryDetails; -using included::AddQueryDetails; - -using included::GetSchema; - -} // namespace exported - -using namespace exported; +using proxy::GetSchema; } // namespace graphql::proxy diff --git a/samples/proxy/schema/QueryObject.ixx b/samples/proxy/schema/QueryObject.ixx index daa0f013..fcc61c1d 100644 --- a/samples/proxy/schema/QueryObject.ixx +++ b/samples/proxy/schema/QueryObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Proxy.QueryObject; -namespace included = graphql::proxy::object; - export namespace graphql::proxy::object { -namespace exported { - -using included::Query; - -} // namespace exported - -using namespace exported; +using object::Query; } // namespace graphql::proxy::object diff --git a/samples/today/nointrospection/AppointmentConnectionObject.ixx b/samples/today/nointrospection/AppointmentConnectionObject.ixx index b9a9f601..ec982810 100644 --- a/samples/today/nointrospection/AppointmentConnectionObject.ixx +++ b/samples/today/nointrospection/AppointmentConnectionObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.AppointmentConnectionObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::AppointmentConnection; - -} // namespace exported - -using namespace exported; +using object::AppointmentConnection; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/AppointmentEdgeObject.ixx b/samples/today/nointrospection/AppointmentEdgeObject.ixx index 2c4e5e77..8d283bf9 100644 --- a/samples/today/nointrospection/AppointmentEdgeObject.ixx +++ b/samples/today/nointrospection/AppointmentEdgeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.AppointmentEdgeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::AppointmentEdge; - -} // namespace exported - -using namespace exported; +using object::AppointmentEdge; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/AppointmentObject.ixx b/samples/today/nointrospection/AppointmentObject.ixx index 4f3a78b2..34131b4b 100644 --- a/samples/today/nointrospection/AppointmentObject.ixx +++ b/samples/today/nointrospection/AppointmentObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.AppointmentObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Appointment; - -} // namespace exported - -using namespace exported; +using object::Appointment; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/CompleteTaskPayloadObject.ixx b/samples/today/nointrospection/CompleteTaskPayloadObject.ixx index 645bb2a8..fe9415d9 100644 --- a/samples/today/nointrospection/CompleteTaskPayloadObject.ixx +++ b/samples/today/nointrospection/CompleteTaskPayloadObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.CompleteTaskPayloadObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::CompleteTaskPayload; - -} // namespace exported - -using namespace exported; +using object::CompleteTaskPayload; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/ExpensiveObject.ixx b/samples/today/nointrospection/ExpensiveObject.ixx index ff03e488..00bf65f4 100644 --- a/samples/today/nointrospection/ExpensiveObject.ixx +++ b/samples/today/nointrospection/ExpensiveObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.ExpensiveObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Expensive; - -} // namespace exported - -using namespace exported; +using object::Expensive; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/FolderConnectionObject.ixx b/samples/today/nointrospection/FolderConnectionObject.ixx index 9ad8b9b6..d5434681 100644 --- a/samples/today/nointrospection/FolderConnectionObject.ixx +++ b/samples/today/nointrospection/FolderConnectionObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.FolderConnectionObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::FolderConnection; - -} // namespace exported - -using namespace exported; +using object::FolderConnection; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/FolderEdgeObject.ixx b/samples/today/nointrospection/FolderEdgeObject.ixx index 6dd06a63..6a6fdf26 100644 --- a/samples/today/nointrospection/FolderEdgeObject.ixx +++ b/samples/today/nointrospection/FolderEdgeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.FolderEdgeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::FolderEdge; - -} // namespace exported - -using namespace exported; +using object::FolderEdge; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/FolderObject.ixx b/samples/today/nointrospection/FolderObject.ixx index f4bf4e11..ca0ee0a7 100644 --- a/samples/today/nointrospection/FolderObject.ixx +++ b/samples/today/nointrospection/FolderObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.FolderObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Folder; - -} // namespace exported - -using namespace exported; +using object::Folder; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/MutationObject.ixx b/samples/today/nointrospection/MutationObject.ixx index 80008cd9..1f20b3b3 100644 --- a/samples/today/nointrospection/MutationObject.ixx +++ b/samples/today/nointrospection/MutationObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.MutationObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Mutation; - -} // namespace exported - -using namespace exported; +using object::Mutation; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/NestedTypeObject.ixx b/samples/today/nointrospection/NestedTypeObject.ixx index 7895972c..15db6dc2 100644 --- a/samples/today/nointrospection/NestedTypeObject.ixx +++ b/samples/today/nointrospection/NestedTypeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.NestedTypeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::NestedType; - -} // namespace exported - -using namespace exported; +using object::NestedType; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/NodeObject.ixx b/samples/today/nointrospection/NodeObject.ixx index eafee7d1..89446202 100644 --- a/samples/today/nointrospection/NodeObject.ixx +++ b/samples/today/nointrospection/NodeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.NodeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Node; - -} // namespace exported - -using namespace exported; +using object::Node; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/PageInfoObject.ixx b/samples/today/nointrospection/PageInfoObject.ixx index f68e2225..ecb6ce42 100644 --- a/samples/today/nointrospection/PageInfoObject.ixx +++ b/samples/today/nointrospection/PageInfoObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.PageInfoObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::PageInfo; - -} // namespace exported - -using namespace exported; +using object::PageInfo; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/QueryObject.ixx b/samples/today/nointrospection/QueryObject.ixx index 5388c782..84d3715c 100644 --- a/samples/today/nointrospection/QueryObject.ixx +++ b/samples/today/nointrospection/QueryObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.QueryObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Query; - -} // namespace exported - -using namespace exported; +using object::Query; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/SubscriptionObject.ixx b/samples/today/nointrospection/SubscriptionObject.ixx index dd90d666..d84fdbd8 100644 --- a/samples/today/nointrospection/SubscriptionObject.ixx +++ b/samples/today/nointrospection/SubscriptionObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.SubscriptionObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Subscription; - -} // namespace exported - -using namespace exported; +using object::Subscription; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/TaskConnectionObject.ixx b/samples/today/nointrospection/TaskConnectionObject.ixx index 1767efeb..8225fa7f 100644 --- a/samples/today/nointrospection/TaskConnectionObject.ixx +++ b/samples/today/nointrospection/TaskConnectionObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.TaskConnectionObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::TaskConnection; - -} // namespace exported - -using namespace exported; +using object::TaskConnection; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/TaskEdgeObject.ixx b/samples/today/nointrospection/TaskEdgeObject.ixx index 61d2bd63..bdf2bba7 100644 --- a/samples/today/nointrospection/TaskEdgeObject.ixx +++ b/samples/today/nointrospection/TaskEdgeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.TaskEdgeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::TaskEdge; - -} // namespace exported - -using namespace exported; +using object::TaskEdge; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/TaskObject.ixx b/samples/today/nointrospection/TaskObject.ixx index 8a3b6e0a..dcf0d814 100644 --- a/samples/today/nointrospection/TaskObject.ixx +++ b/samples/today/nointrospection/TaskObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.TaskObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Task; - -} // namespace exported - -using namespace exported; +using object::Task; } // namespace graphql::today::object diff --git a/samples/today/nointrospection/TodaySchema.ixx b/samples/today/nointrospection/TodaySchema.ixx index 7c1f5d30..0230a5ab 100644 --- a/samples/today/nointrospection/TodaySchema.ixx +++ b/samples/today/nointrospection/TodaySchema.ixx @@ -13,47 +13,41 @@ namespace included = graphql::today; export namespace graphql::today { -namespace exported { - -using included::TaskState; -using included::getTaskStateNames; -using included::getTaskStateValues; - -using included::CompleteTaskInput; -using included::ThirdNestedInput; -using included::FourthNestedInput; -using included::IncludeNullableSelfInput; -using included::IncludeNonNullableListSelfInput; -using included::StringOperationFilterInput; -using included::SecondNestedInput; -using included::ForwardDeclaredInput; -using included::FirstNestedInput; - -using included::Operations; - -using included::AddNodeDetails; -using included::AddUnionTypeDetails; -using included::AddQueryDetails; -using included::AddPageInfoDetails; -using included::AddAppointmentEdgeDetails; -using included::AddAppointmentConnectionDetails; -using included::AddTaskEdgeDetails; -using included::AddTaskConnectionDetails; -using included::AddFolderEdgeDetails; -using included::AddFolderConnectionDetails; -using included::AddCompleteTaskPayloadDetails; -using included::AddMutationDetails; -using included::AddSubscriptionDetails; -using included::AddAppointmentDetails; -using included::AddTaskDetails; -using included::AddFolderDetails; -using included::AddNestedTypeDetails; -using included::AddExpensiveDetails; - -using included::GetSchema; - -} // namespace exported - -using namespace exported; +using today::TaskState; +using today::getTaskStateNames; +using today::getTaskStateValues; + +using today::CompleteTaskInput; +using today::ThirdNestedInput; +using today::FourthNestedInput; +using today::IncludeNullableSelfInput; +using today::IncludeNonNullableListSelfInput; +using today::StringOperationFilterInput; +using today::SecondNestedInput; +using today::ForwardDeclaredInput; +using today::FirstNestedInput; + +using today::Operations; + +using today::AddNodeDetails; +using today::AddUnionTypeDetails; +using today::AddQueryDetails; +using today::AddPageInfoDetails; +using today::AddAppointmentEdgeDetails; +using today::AddAppointmentConnectionDetails; +using today::AddTaskEdgeDetails; +using today::AddTaskConnectionDetails; +using today::AddFolderEdgeDetails; +using today::AddFolderConnectionDetails; +using today::AddCompleteTaskPayloadDetails; +using today::AddMutationDetails; +using today::AddSubscriptionDetails; +using today::AddAppointmentDetails; +using today::AddTaskDetails; +using today::AddFolderDetails; +using today::AddNestedTypeDetails; +using today::AddExpensiveDetails; + +using today::GetSchema; } // namespace graphql::today diff --git a/samples/today/nointrospection/UnionTypeObject.ixx b/samples/today/nointrospection/UnionTypeObject.ixx index 362b8a41..bfd588fd 100644 --- a/samples/today/nointrospection/UnionTypeObject.ixx +++ b/samples/today/nointrospection/UnionTypeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.UnionTypeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::UnionType; - -} // namespace exported - -using namespace exported; +using object::UnionType; } // namespace graphql::today::object diff --git a/samples/today/schema/AppointmentConnectionObject.ixx b/samples/today/schema/AppointmentConnectionObject.ixx index b9a9f601..ec982810 100644 --- a/samples/today/schema/AppointmentConnectionObject.ixx +++ b/samples/today/schema/AppointmentConnectionObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.AppointmentConnectionObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::AppointmentConnection; - -} // namespace exported - -using namespace exported; +using object::AppointmentConnection; } // namespace graphql::today::object diff --git a/samples/today/schema/AppointmentEdgeObject.ixx b/samples/today/schema/AppointmentEdgeObject.ixx index 2c4e5e77..8d283bf9 100644 --- a/samples/today/schema/AppointmentEdgeObject.ixx +++ b/samples/today/schema/AppointmentEdgeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.AppointmentEdgeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::AppointmentEdge; - -} // namespace exported - -using namespace exported; +using object::AppointmentEdge; } // namespace graphql::today::object diff --git a/samples/today/schema/AppointmentObject.ixx b/samples/today/schema/AppointmentObject.ixx index 4f3a78b2..34131b4b 100644 --- a/samples/today/schema/AppointmentObject.ixx +++ b/samples/today/schema/AppointmentObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.AppointmentObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Appointment; - -} // namespace exported - -using namespace exported; +using object::Appointment; } // namespace graphql::today::object diff --git a/samples/today/schema/CompleteTaskPayloadObject.ixx b/samples/today/schema/CompleteTaskPayloadObject.ixx index 645bb2a8..fe9415d9 100644 --- a/samples/today/schema/CompleteTaskPayloadObject.ixx +++ b/samples/today/schema/CompleteTaskPayloadObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.CompleteTaskPayloadObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::CompleteTaskPayload; - -} // namespace exported - -using namespace exported; +using object::CompleteTaskPayload; } // namespace graphql::today::object diff --git a/samples/today/schema/ExpensiveObject.ixx b/samples/today/schema/ExpensiveObject.ixx index ff03e488..00bf65f4 100644 --- a/samples/today/schema/ExpensiveObject.ixx +++ b/samples/today/schema/ExpensiveObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.ExpensiveObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Expensive; - -} // namespace exported - -using namespace exported; +using object::Expensive; } // namespace graphql::today::object diff --git a/samples/today/schema/FolderConnectionObject.ixx b/samples/today/schema/FolderConnectionObject.ixx index 9ad8b9b6..d5434681 100644 --- a/samples/today/schema/FolderConnectionObject.ixx +++ b/samples/today/schema/FolderConnectionObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.FolderConnectionObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::FolderConnection; - -} // namespace exported - -using namespace exported; +using object::FolderConnection; } // namespace graphql::today::object diff --git a/samples/today/schema/FolderEdgeObject.ixx b/samples/today/schema/FolderEdgeObject.ixx index 6dd06a63..6a6fdf26 100644 --- a/samples/today/schema/FolderEdgeObject.ixx +++ b/samples/today/schema/FolderEdgeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.FolderEdgeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::FolderEdge; - -} // namespace exported - -using namespace exported; +using object::FolderEdge; } // namespace graphql::today::object diff --git a/samples/today/schema/FolderObject.ixx b/samples/today/schema/FolderObject.ixx index f4bf4e11..ca0ee0a7 100644 --- a/samples/today/schema/FolderObject.ixx +++ b/samples/today/schema/FolderObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.FolderObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Folder; - -} // namespace exported - -using namespace exported; +using object::Folder; } // namespace graphql::today::object diff --git a/samples/today/schema/MutationObject.ixx b/samples/today/schema/MutationObject.ixx index 80008cd9..1f20b3b3 100644 --- a/samples/today/schema/MutationObject.ixx +++ b/samples/today/schema/MutationObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.MutationObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Mutation; - -} // namespace exported - -using namespace exported; +using object::Mutation; } // namespace graphql::today::object diff --git a/samples/today/schema/NestedTypeObject.ixx b/samples/today/schema/NestedTypeObject.ixx index 7895972c..15db6dc2 100644 --- a/samples/today/schema/NestedTypeObject.ixx +++ b/samples/today/schema/NestedTypeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.NestedTypeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::NestedType; - -} // namespace exported - -using namespace exported; +using object::NestedType; } // namespace graphql::today::object diff --git a/samples/today/schema/NodeObject.ixx b/samples/today/schema/NodeObject.ixx index eafee7d1..89446202 100644 --- a/samples/today/schema/NodeObject.ixx +++ b/samples/today/schema/NodeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.NodeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Node; - -} // namespace exported - -using namespace exported; +using object::Node; } // namespace graphql::today::object diff --git a/samples/today/schema/PageInfoObject.ixx b/samples/today/schema/PageInfoObject.ixx index f68e2225..ecb6ce42 100644 --- a/samples/today/schema/PageInfoObject.ixx +++ b/samples/today/schema/PageInfoObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.PageInfoObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::PageInfo; - -} // namespace exported - -using namespace exported; +using object::PageInfo; } // namespace graphql::today::object diff --git a/samples/today/schema/QueryObject.ixx b/samples/today/schema/QueryObject.ixx index 5388c782..84d3715c 100644 --- a/samples/today/schema/QueryObject.ixx +++ b/samples/today/schema/QueryObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.QueryObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Query; - -} // namespace exported - -using namespace exported; +using object::Query; } // namespace graphql::today::object diff --git a/samples/today/schema/SubscriptionObject.ixx b/samples/today/schema/SubscriptionObject.ixx index dd90d666..d84fdbd8 100644 --- a/samples/today/schema/SubscriptionObject.ixx +++ b/samples/today/schema/SubscriptionObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.SubscriptionObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Subscription; - -} // namespace exported - -using namespace exported; +using object::Subscription; } // namespace graphql::today::object diff --git a/samples/today/schema/TaskConnectionObject.ixx b/samples/today/schema/TaskConnectionObject.ixx index 1767efeb..8225fa7f 100644 --- a/samples/today/schema/TaskConnectionObject.ixx +++ b/samples/today/schema/TaskConnectionObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.TaskConnectionObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::TaskConnection; - -} // namespace exported - -using namespace exported; +using object::TaskConnection; } // namespace graphql::today::object diff --git a/samples/today/schema/TaskEdgeObject.ixx b/samples/today/schema/TaskEdgeObject.ixx index 61d2bd63..bdf2bba7 100644 --- a/samples/today/schema/TaskEdgeObject.ixx +++ b/samples/today/schema/TaskEdgeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.TaskEdgeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::TaskEdge; - -} // namespace exported - -using namespace exported; +using object::TaskEdge; } // namespace graphql::today::object diff --git a/samples/today/schema/TaskObject.ixx b/samples/today/schema/TaskObject.ixx index 8a3b6e0a..dcf0d814 100644 --- a/samples/today/schema/TaskObject.ixx +++ b/samples/today/schema/TaskObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.TaskObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::Task; - -} // namespace exported - -using namespace exported; +using object::Task; } // namespace graphql::today::object diff --git a/samples/today/schema/TodaySchema.ixx b/samples/today/schema/TodaySchema.ixx index 7c1f5d30..0230a5ab 100644 --- a/samples/today/schema/TodaySchema.ixx +++ b/samples/today/schema/TodaySchema.ixx @@ -13,47 +13,41 @@ namespace included = graphql::today; export namespace graphql::today { -namespace exported { - -using included::TaskState; -using included::getTaskStateNames; -using included::getTaskStateValues; - -using included::CompleteTaskInput; -using included::ThirdNestedInput; -using included::FourthNestedInput; -using included::IncludeNullableSelfInput; -using included::IncludeNonNullableListSelfInput; -using included::StringOperationFilterInput; -using included::SecondNestedInput; -using included::ForwardDeclaredInput; -using included::FirstNestedInput; - -using included::Operations; - -using included::AddNodeDetails; -using included::AddUnionTypeDetails; -using included::AddQueryDetails; -using included::AddPageInfoDetails; -using included::AddAppointmentEdgeDetails; -using included::AddAppointmentConnectionDetails; -using included::AddTaskEdgeDetails; -using included::AddTaskConnectionDetails; -using included::AddFolderEdgeDetails; -using included::AddFolderConnectionDetails; -using included::AddCompleteTaskPayloadDetails; -using included::AddMutationDetails; -using included::AddSubscriptionDetails; -using included::AddAppointmentDetails; -using included::AddTaskDetails; -using included::AddFolderDetails; -using included::AddNestedTypeDetails; -using included::AddExpensiveDetails; - -using included::GetSchema; - -} // namespace exported - -using namespace exported; +using today::TaskState; +using today::getTaskStateNames; +using today::getTaskStateValues; + +using today::CompleteTaskInput; +using today::ThirdNestedInput; +using today::FourthNestedInput; +using today::IncludeNullableSelfInput; +using today::IncludeNonNullableListSelfInput; +using today::StringOperationFilterInput; +using today::SecondNestedInput; +using today::ForwardDeclaredInput; +using today::FirstNestedInput; + +using today::Operations; + +using today::AddNodeDetails; +using today::AddUnionTypeDetails; +using today::AddQueryDetails; +using today::AddPageInfoDetails; +using today::AddAppointmentEdgeDetails; +using today::AddAppointmentConnectionDetails; +using today::AddTaskEdgeDetails; +using today::AddTaskConnectionDetails; +using today::AddFolderEdgeDetails; +using today::AddFolderConnectionDetails; +using today::AddCompleteTaskPayloadDetails; +using today::AddMutationDetails; +using today::AddSubscriptionDetails; +using today::AddAppointmentDetails; +using today::AddTaskDetails; +using today::AddFolderDetails; +using today::AddNestedTypeDetails; +using today::AddExpensiveDetails; + +using today::GetSchema; } // namespace graphql::today diff --git a/samples/today/schema/UnionTypeObject.ixx b/samples/today/schema/UnionTypeObject.ixx index 362b8a41..bfd588fd 100644 --- a/samples/today/schema/UnionTypeObject.ixx +++ b/samples/today/schema/UnionTypeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Today.UnionTypeObject; -namespace included = graphql::today::object; - export namespace graphql::today::object { -namespace exported { - -using included::UnionType; - -} // namespace exported - -using namespace exported; +using object::UnionType; } // namespace graphql::today::object diff --git a/samples/validation/schema/AlienObject.ixx b/samples/validation/schema/AlienObject.ixx index fa01c412..54db3153 100644 --- a/samples/validation/schema/AlienObject.ixx +++ b/samples/validation/schema/AlienObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.AlienObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Alien; - -} // namespace exported - -using namespace exported; +using object::Alien; } // namespace graphql::validation::object diff --git a/samples/validation/schema/ArgumentsObject.ixx b/samples/validation/schema/ArgumentsObject.ixx index e6f5fced..dc4502c7 100644 --- a/samples/validation/schema/ArgumentsObject.ixx +++ b/samples/validation/schema/ArgumentsObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.ArgumentsObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Arguments; - -} // namespace exported - -using namespace exported; +using object::Arguments; } // namespace graphql::validation::object diff --git a/samples/validation/schema/CatObject.ixx b/samples/validation/schema/CatObject.ixx index e2612a95..74415bca 100644 --- a/samples/validation/schema/CatObject.ixx +++ b/samples/validation/schema/CatObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.CatObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Cat; - -} // namespace exported - -using namespace exported; +using object::Cat; } // namespace graphql::validation::object diff --git a/samples/validation/schema/CatOrDogObject.ixx b/samples/validation/schema/CatOrDogObject.ixx index ee6327b3..ed07b094 100644 --- a/samples/validation/schema/CatOrDogObject.ixx +++ b/samples/validation/schema/CatOrDogObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.CatOrDogObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::CatOrDog; - -} // namespace exported - -using namespace exported; +using object::CatOrDog; } // namespace graphql::validation::object diff --git a/samples/validation/schema/DogObject.ixx b/samples/validation/schema/DogObject.ixx index 7658ad3b..14b6f3e8 100644 --- a/samples/validation/schema/DogObject.ixx +++ b/samples/validation/schema/DogObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.DogObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Dog; - -} // namespace exported - -using namespace exported; +using object::Dog; } // namespace graphql::validation::object diff --git a/samples/validation/schema/DogOrHumanObject.ixx b/samples/validation/schema/DogOrHumanObject.ixx index 3b79e779..e301fe5b 100644 --- a/samples/validation/schema/DogOrHumanObject.ixx +++ b/samples/validation/schema/DogOrHumanObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.DogOrHumanObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::DogOrHuman; - -} // namespace exported - -using namespace exported; +using object::DogOrHuman; } // namespace graphql::validation::object diff --git a/samples/validation/schema/HumanObject.ixx b/samples/validation/schema/HumanObject.ixx index e8f263a3..cc70f3ce 100644 --- a/samples/validation/schema/HumanObject.ixx +++ b/samples/validation/schema/HumanObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.HumanObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Human; - -} // namespace exported - -using namespace exported; +using object::Human; } // namespace graphql::validation::object diff --git a/samples/validation/schema/HumanOrAlienObject.ixx b/samples/validation/schema/HumanOrAlienObject.ixx index a43fbac6..8deb8777 100644 --- a/samples/validation/schema/HumanOrAlienObject.ixx +++ b/samples/validation/schema/HumanOrAlienObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.HumanOrAlienObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::HumanOrAlien; - -} // namespace exported - -using namespace exported; +using object::HumanOrAlien; } // namespace graphql::validation::object diff --git a/samples/validation/schema/MessageObject.ixx b/samples/validation/schema/MessageObject.ixx index 2564a7ec..3ee9c892 100644 --- a/samples/validation/schema/MessageObject.ixx +++ b/samples/validation/schema/MessageObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.MessageObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Message; - -} // namespace exported - -using namespace exported; +using object::Message; } // namespace graphql::validation::object diff --git a/samples/validation/schema/MutateDogResultObject.ixx b/samples/validation/schema/MutateDogResultObject.ixx index a1191701..fb8915c7 100644 --- a/samples/validation/schema/MutateDogResultObject.ixx +++ b/samples/validation/schema/MutateDogResultObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.MutateDogResultObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::MutateDogResult; - -} // namespace exported - -using namespace exported; +using object::MutateDogResult; } // namespace graphql::validation::object diff --git a/samples/validation/schema/MutationObject.ixx b/samples/validation/schema/MutationObject.ixx index f3653039..3e61de52 100644 --- a/samples/validation/schema/MutationObject.ixx +++ b/samples/validation/schema/MutationObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.MutationObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Mutation; - -} // namespace exported - -using namespace exported; +using object::Mutation; } // namespace graphql::validation::object diff --git a/samples/validation/schema/NodeObject.ixx b/samples/validation/schema/NodeObject.ixx index 09bfc3fe..f3d91fde 100644 --- a/samples/validation/schema/NodeObject.ixx +++ b/samples/validation/schema/NodeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.NodeObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Node; - -} // namespace exported - -using namespace exported; +using object::Node; } // namespace graphql::validation::object diff --git a/samples/validation/schema/PetObject.ixx b/samples/validation/schema/PetObject.ixx index 19fe3ea3..9c77c197 100644 --- a/samples/validation/schema/PetObject.ixx +++ b/samples/validation/schema/PetObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.PetObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Pet; - -} // namespace exported - -using namespace exported; +using object::Pet; } // namespace graphql::validation::object diff --git a/samples/validation/schema/QueryObject.ixx b/samples/validation/schema/QueryObject.ixx index 0cc191ee..f25b794a 100644 --- a/samples/validation/schema/QueryObject.ixx +++ b/samples/validation/schema/QueryObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.QueryObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Query; - -} // namespace exported - -using namespace exported; +using object::Query; } // namespace graphql::validation::object diff --git a/samples/validation/schema/ResourceObject.ixx b/samples/validation/schema/ResourceObject.ixx index ac491835..6fd30498 100644 --- a/samples/validation/schema/ResourceObject.ixx +++ b/samples/validation/schema/ResourceObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.ResourceObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Resource; - -} // namespace exported - -using namespace exported; +using object::Resource; } // namespace graphql::validation::object diff --git a/samples/validation/schema/SentientObject.ixx b/samples/validation/schema/SentientObject.ixx index 7e19233c..9793549c 100644 --- a/samples/validation/schema/SentientObject.ixx +++ b/samples/validation/schema/SentientObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.SentientObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Sentient; - -} // namespace exported - -using namespace exported; +using object::Sentient; } // namespace graphql::validation::object diff --git a/samples/validation/schema/SubscriptionObject.ixx b/samples/validation/schema/SubscriptionObject.ixx index 571e57a2..db16c987 100644 --- a/samples/validation/schema/SubscriptionObject.ixx +++ b/samples/validation/schema/SubscriptionObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Validation.SubscriptionObject; -namespace included = graphql::validation::object; - export namespace graphql::validation::object { -namespace exported { - -using included::Subscription; - -} // namespace exported - -using namespace exported; +using object::Subscription; } // namespace graphql::validation::object diff --git a/samples/validation/schema/ValidationSchema.ixx b/samples/validation/schema/ValidationSchema.ixx index 4ecd7eeb..a4083ca0 100644 --- a/samples/validation/schema/ValidationSchema.ixx +++ b/samples/validation/schema/ValidationSchema.ixx @@ -13,42 +13,36 @@ namespace included = graphql::validation; export namespace graphql::validation { -namespace exported { - -using included::DogCommand; -using included::getDogCommandNames; -using included::getDogCommandValues; - -using included::CatCommand; -using included::getCatCommandNames; -using included::getCatCommandValues; - -using included::ComplexInput; - -using included::Operations; - -using included::AddSentientDetails; -using included::AddPetDetails; -using included::AddNodeDetails; -using included::AddResourceDetails; -using included::AddCatOrDogDetails; -using included::AddDogOrHumanDetails; -using included::AddHumanOrAlienDetails; -using included::AddQueryDetails; -using included::AddDogDetails; -using included::AddAlienDetails; -using included::AddHumanDetails; -using included::AddCatDetails; -using included::AddMutationDetails; -using included::AddMutateDogResultDetails; -using included::AddSubscriptionDetails; -using included::AddMessageDetails; -using included::AddArgumentsDetails; - -using included::GetSchema; - -} // namespace exported - -using namespace exported; +using validation::DogCommand; +using validation::getDogCommandNames; +using validation::getDogCommandValues; + +using validation::CatCommand; +using validation::getCatCommandNames; +using validation::getCatCommandValues; + +using validation::ComplexInput; + +using validation::Operations; + +using validation::AddSentientDetails; +using validation::AddPetDetails; +using validation::AddNodeDetails; +using validation::AddResourceDetails; +using validation::AddCatOrDogDetails; +using validation::AddDogOrHumanDetails; +using validation::AddHumanOrAlienDetails; +using validation::AddQueryDetails; +using validation::AddDogDetails; +using validation::AddAlienDetails; +using validation::AddHumanDetails; +using validation::AddCatDetails; +using validation::AddMutationDetails; +using validation::AddMutateDogResultDetails; +using validation::AddSubscriptionDetails; +using validation::AddMessageDetails; +using validation::AddArgumentsDetails; + +using validation::GetSchema; } // namespace graphql::validation diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index cb76a36f..193bb1c6 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -620,10 +620,6 @@ bool Generator::outputModule() const noexcept std::ofstream moduleFile(_modulePath, std::ios_base::trunc); std::ostringstream ossNamespace; - ossNamespace << getClientNamespace() << R"cpp(::)cpp"; - - const auto clientNamespace = ossNamespace.str(); - moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. @@ -640,16 +636,12 @@ export module GraphQL.)cpp" << _schemaLoader.getFilenamePrefix() << R"cpp(Client; -namespace included = )cpp" - << getClientNamespace() << R"cpp(; - export )cpp"; NamespaceScope graphqlNamespace { moduleFile, getClientNamespace() }; moduleFile << std::endl; - NamespaceScope exportedNamespace { moduleFile, "exported" }; NamespaceScope schemaNamespace { moduleFile, _schemaLoader.getSchemaNamespace(), true }; PendingBlankLine pendingSeparator { moduleFile }; @@ -657,10 +649,10 @@ export )cpp"; if (schemaNamespace.enter()) { moduleFile << R"cpp( -using included::)cpp" - << _schemaLoader.getSchemaNamespace() << R"cpp(::GetRequestText; -using included::)cpp" - << _schemaLoader.getSchemaNamespace() << R"cpp(::GetRequestObject; +using )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::GetRequestText; +using )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::GetRequestObject; )cpp"; pendingSeparator.add(); } @@ -684,7 +676,7 @@ using included::)cpp" continue; } - moduleFile << R"cpp(using included::)cpp" << _schemaLoader.getSchemaNamespace() + moduleFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << cppType << R"cpp(; )cpp"; } @@ -715,7 +707,7 @@ using included::)cpp" continue; } - moduleFile << R"cpp(using included::)cpp" << _schemaLoader.getSchemaNamespace() + moduleFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << cppType << R"cpp(; )cpp"; } @@ -738,22 +730,23 @@ using included::)cpp" pendingSeparator.reset(); NamespaceScope operationNamespaceScope { moduleFile, getOperationNamespace(operation) }; + const auto operationNamespace = _requestLoader.getOperationNamespace(operation); moduleFile << R"cpp( -using included::)cpp" - << _schemaLoader.getSchemaNamespace() << R"cpp(::GetRequestText; -using included::)cpp" - << _schemaLoader.getSchemaNamespace() << R"cpp(::GetRequestObject; -using included::)cpp" - << getOperationNamespace(operation) << R"cpp(::GetOperationName; +using )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::GetRequestText; +using )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::GetRequestObject; +using )cpp" << operationNamespace + << R"cpp(::GetOperationName; )cpp"; // Alias all of the enums referenced either in variables or the response. for (const auto& enumType : _requestLoader.getReferencedEnums(operation)) { - moduleFile << R"cpp(using included::)cpp" << _schemaLoader.getSchemaNamespace() - << R"cpp(::)cpp" << _schemaLoader.getCppType(enumType->name()) << R"cpp(; + moduleFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" + << _schemaLoader.getCppType(enumType->name()) << R"cpp(; )cpp"; pendingSeparator.add(); @@ -764,9 +757,8 @@ using included::)cpp" // Alias all of the input object structs referenced in variables. for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) { - moduleFile << R"cpp(using included::)cpp" << _schemaLoader.getSchemaNamespace() - << R"cpp(::)cpp" << _schemaLoader.getCppType(inputType.type->name()) - << R"cpp(; + moduleFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" + << _schemaLoader.getCppType(inputType.type->name()) << R"cpp(; )cpp"; pendingSeparator.add(); @@ -778,9 +770,8 @@ using included::)cpp" if (!variables.empty()) { - moduleFile << R"cpp(using included::)cpp" << getOperationNamespace(operation) - << R"cpp(::Variables; -using included::)cpp" << getOperationNamespace(operation) + moduleFile << R"cpp(using )cpp" << operationNamespace << R"cpp(::Variables; +using )cpp" << operationNamespace << R"cpp(::serializeVariables; )cpp"; @@ -789,13 +780,12 @@ using included::)cpp" << getOperationNamespace(operation) pendingSeparator.reset(); - moduleFile << R"cpp(using included::)cpp" << getOperationNamespace(operation) - << R"cpp(::Response; -using included::)cpp" - << getOperationNamespace(operation) << R"cpp(::parseResponse; + moduleFile << R"cpp(using )cpp" << operationNamespace << R"cpp(::Response; +using )cpp" << operationNamespace + << R"cpp(::parseResponse; -using included::)cpp" - << getOperationNamespace(operation) << R"cpp(::Traits; +using )cpp" << operationNamespace + << R"cpp(::Traits; )cpp"; @@ -804,14 +794,6 @@ using included::)cpp" pendingSeparator.reset(); - if (exportedNamespace.exit()) - { - moduleFile << R"cpp( -using namespace exported; - -)cpp"; - } - return true; } diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 8b21a3e8..0be8f71e 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -715,10 +715,6 @@ namespace included = )cpp" export )cpp"; NamespaceScope graphqlNamespace { moduleFile, schemaNamespace }; - - moduleFile << std::endl; - - NamespaceScope exportedNamespace { moduleFile, "exported" }; PendingBlankLine pendingSeparator { moduleFile }; if (!_loader.getEnumTypes().empty()) @@ -727,11 +723,12 @@ export )cpp"; for (const auto& enumType : _loader.getEnumTypes()) { - moduleFile << R"cpp(using included::)cpp" << enumType.cppType << R"cpp(; -using included::get)cpp" - << enumType.cppType << R"cpp(Names; -using included::get)cpp" - << enumType.cppType << R"cpp(Values; + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" + << enumType.cppType << R"cpp(; +using )cpp" << _loader.getSchemaNamespace() + << R"cpp(::get)cpp" << enumType.cppType << R"cpp(Names; +using )cpp" << _loader.getSchemaNamespace() + << R"cpp(::get)cpp" << enumType.cppType << R"cpp(Values; )cpp"; } @@ -743,7 +740,8 @@ using included::get)cpp" for (const auto& inputType : _loader.getInputTypes()) { - moduleFile << R"cpp(using included::)cpp" << inputType.cppType << R"cpp(; + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" + << inputType.cppType << R"cpp(; )cpp"; } @@ -754,7 +752,7 @@ using included::get)cpp" { pendingSeparator.reset(); - moduleFile << R"cpp(using included::Operations; + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Operations; )cpp"; } @@ -765,7 +763,8 @@ using included::get)cpp" for (const auto& interfaceType : _loader.getInterfaceTypes()) { - moduleFile << R"cpp(using included::Add)cpp" << interfaceType.cppType << R"cpp(Details; + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Add)cpp" + << interfaceType.cppType << R"cpp(Details; )cpp"; } } @@ -776,7 +775,8 @@ using included::get)cpp" for (const auto& unionType : _loader.getUnionTypes()) { - moduleFile << R"cpp(using included::Add)cpp" << unionType.cppType << R"cpp(Details; + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Add)cpp" + << unionType.cppType << R"cpp(Details; )cpp"; } } @@ -787,7 +787,8 @@ using included::get)cpp" for (const auto& objectType : _loader.getObjectTypes()) { - moduleFile << R"cpp(using included::Add)cpp" << objectType.cppType << R"cpp(Details; + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Add)cpp" + << objectType.cppType << R"cpp(Details; )cpp"; } } @@ -795,22 +796,16 @@ using included::get)cpp" if (_loader.isIntrospection()) { moduleFile << R"cpp( -using included::AddTypesToSchema; +using )cpp" << _loader.getSchemaNamespace() + << R"cpp(::AddTypesToSchema; )cpp"; } else { moduleFile << R"cpp( -using included::GetSchema; - -)cpp"; - } - - if (exportedNamespace.exit()) - { - moduleFile << R"cpp( -using namespace exported; +using )cpp" << _loader.getSchemaNamespace() + << R"cpp(::GetSchema; )cpp"; } @@ -908,21 +903,12 @@ module; export module GraphQL.)cpp" << _loader.getFilenamePrefix() << R"cpp(.)cpp" << cppType << R"cpp(Object; -namespace included = )cpp" - << objectNamespace << R"cpp(; - export namespace )cpp" << objectNamespace << R"cpp( { -namespace exported { - -using included::)cpp" +using object::)cpp" << cppType << R"cpp(; -} // namespace exported - -using namespace exported; - } // namespace )cpp" << objectNamespace << R"cpp( )cpp"; diff --git a/src/introspection/DirectiveObject.ixx b/src/introspection/DirectiveObject.ixx index 97f3dae7..8a00c78d 100644 --- a/src/introspection/DirectiveObject.ixx +++ b/src/introspection/DirectiveObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.DirectiveObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::Directive; - -} // namespace exported - -using namespace exported; +using object::Directive; } // namespace graphql::introspection::object diff --git a/src/introspection/EnumValueObject.ixx b/src/introspection/EnumValueObject.ixx index 572acd70..45be5d13 100644 --- a/src/introspection/EnumValueObject.ixx +++ b/src/introspection/EnumValueObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.EnumValueObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::EnumValue; - -} // namespace exported - -using namespace exported; +using object::EnumValue; } // namespace graphql::introspection::object diff --git a/src/introspection/FieldObject.ixx b/src/introspection/FieldObject.ixx index b98ed284..aa5c8305 100644 --- a/src/introspection/FieldObject.ixx +++ b/src/introspection/FieldObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.FieldObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::Field; - -} // namespace exported - -using namespace exported; +using object::Field; } // namespace graphql::introspection::object diff --git a/src/introspection/InputValueObject.ixx b/src/introspection/InputValueObject.ixx index b3ca2cfd..252760df 100644 --- a/src/introspection/InputValueObject.ixx +++ b/src/introspection/InputValueObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.InputValueObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::InputValue; - -} // namespace exported - -using namespace exported; +using object::InputValue; } // namespace graphql::introspection::object diff --git a/src/introspection/IntrospectionSchema.ixx b/src/introspection/IntrospectionSchema.ixx index 77d96507..2044667f 100644 --- a/src/introspection/IntrospectionSchema.ixx +++ b/src/introspection/IntrospectionSchema.ixx @@ -13,27 +13,21 @@ namespace included = graphql::introspection; export namespace graphql::introspection { -namespace exported { - -using included::TypeKind; -using included::getTypeKindNames; -using included::getTypeKindValues; - -using included::DirectiveLocation; -using included::getDirectiveLocationNames; -using included::getDirectiveLocationValues; - -using included::AddSchemaDetails; -using included::AddTypeDetails; -using included::AddFieldDetails; -using included::AddInputValueDetails; -using included::AddEnumValueDetails; -using included::AddDirectiveDetails; - -using included::AddTypesToSchema; - -} // namespace exported - -using namespace exported; +using introspection::TypeKind; +using introspection::getTypeKindNames; +using introspection::getTypeKindValues; + +using introspection::DirectiveLocation; +using introspection::getDirectiveLocationNames; +using introspection::getDirectiveLocationValues; + +using introspection::AddSchemaDetails; +using introspection::AddTypeDetails; +using introspection::AddFieldDetails; +using introspection::AddInputValueDetails; +using introspection::AddEnumValueDetails; +using introspection::AddDirectiveDetails; + +using introspection::AddTypesToSchema; } // namespace graphql::introspection diff --git a/src/introspection/SchemaObject.ixx b/src/introspection/SchemaObject.ixx index 063cc3f7..56735d85 100644 --- a/src/introspection/SchemaObject.ixx +++ b/src/introspection/SchemaObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.SchemaObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::Schema; - -} // namespace exported - -using namespace exported; +using object::Schema; } // namespace graphql::introspection::object diff --git a/src/introspection/TypeObject.ixx b/src/introspection/TypeObject.ixx index 401a9329..001ccdd6 100644 --- a/src/introspection/TypeObject.ixx +++ b/src/introspection/TypeObject.ixx @@ -9,16 +9,8 @@ module; export module GraphQL.Introspection.TypeObject; -namespace included = graphql::introspection::object; - export namespace graphql::introspection::object { -namespace exported { - -using included::Type; - -} // namespace exported - -using namespace exported; +using object::Type; } // namespace graphql::introspection::object From c06996cf3d66631a4624822c73abc8d28d639f51 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 16:23:11 -0700 Subject: [PATCH 041/123] fix(include): include algorithm for std::sort --- samples/client/benchmark.cpp | 1 + samples/today/TodayMock.ixx | 12 ++++++------ samples/today/benchmark.cpp | 1 + src/ClientGenerator.cpp | 1 + src/SchemaGenerator.cpp | 1 + 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/samples/client/benchmark.cpp b/samples/client/benchmark.cpp index a677d461..d8a8d79e 100644 --- a/samples/client/benchmark.cpp +++ b/samples/client/benchmark.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#include #include #include #include diff --git a/samples/today/TodayMock.ixx b/samples/today/TodayMock.ixx index a9cc7cb7..2a4af79f 100644 --- a/samples/today/TodayMock.ixx +++ b/samples/today/TodayMock.ixx @@ -17,6 +17,12 @@ export module GraphQL.Today.Mock; export import GraphQL.Response; export import GraphQL.Service; +export import GraphQL.Today.TodaySchema; + +export import GraphQL.Today.QueryObject; +export import GraphQL.Today.MutationObject; +export import GraphQL.Today.SubscriptionObject; + export import GraphQL.Today.AppointmentEdgeObject; export import GraphQL.Today.AppointmentObject; export import GraphQL.Today.AppointmentConnectionObject; @@ -33,12 +39,6 @@ export import GraphQL.Today.TaskEdgeObject; export import GraphQL.Today.TaskObject; export import GraphQL.Today.UnionTypeObject; -export import GraphQL.Today.QueryObject; -export import GraphQL.Today.MutationObject; -export import GraphQL.Today.SubscriptionObject; - -export import GraphQL.Today.TodaySchema; - export namespace graphql::today { // These IDs are hard-coded in every test which uses TodayMock. diff --git a/samples/today/benchmark.cpp b/samples/today/benchmark.cpp index 5c2dd588..168563d6 100644 --- a/samples/today/benchmark.cpp +++ b/samples/today/benchmark.cpp @@ -3,6 +3,7 @@ #include "graphqlservice/JSONResponse.h" +#include #include #include #include diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 193bb1c6..e3bca07d 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -19,6 +19,7 @@ #pragma warning(pop) #endif // _MSC_VER +#include #include #include #include diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 0be8f71e..d2af0e43 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -18,6 +18,7 @@ #pragma warning(pop) #endif // _MSC_VER +#include #include #include #include From c850bbcc03eecfba557db07168cfece786da712b Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 16:43:16 -0700 Subject: [PATCH 042/123] fix(modules): make sure all consumers of todaygraphql use C++20 --- samples/today/CMakeLists.txt | 4 ++++ test/CMakeLists.txt | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/samples/today/CMakeLists.txt b/samples/today/CMakeLists.txt index ff5bbace..9642b50e 100644 --- a/samples/today/CMakeLists.txt +++ b/samples/today/CMakeLists.txt @@ -29,24 +29,28 @@ endif() # sample add_executable(sample sample.cpp) +target_compile_features(sample PUBLIC cxx_std_20) target_link_libraries(sample PRIVATE todaygraphql graphqljson) # sample_nointrospection add_executable(sample_nointrospection sample.cpp) +target_compile_features(sample_nointrospection PUBLIC cxx_std_20) target_link_libraries(sample_nointrospection PRIVATE todaygraphql_nointrospection graphqljson) # benchmark add_executable(benchmark benchmark.cpp) +target_compile_features(benchmark PUBLIC cxx_std_20) target_link_libraries(benchmark PRIVATE todaygraphql graphqljson) # benchmark_nointrospection add_executable(benchmark_nointrospection benchmark.cpp) +target_compile_features(benchmark_nointrospection PUBLIC cxx_std_20) target_link_libraries(benchmark_nointrospection PRIVATE todaygraphql_nointrospection graphqljson) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9e0a8150..e845c1ef 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,6 +15,7 @@ add_bigobj_flag(validation_tests) gtest_add_tests(TARGET validation_tests) add_executable(today_tests TodayTests.cpp) +target_compile_features(today_tests PRIVATE cxx_std_20) target_link_libraries(today_tests PRIVATE todaygraphql graphqljson @@ -24,6 +25,7 @@ add_bigobj_flag(today_tests) gtest_add_tests(TARGET today_tests) add_executable(coroutine_tests CoroutineTests.cpp) +target_compile_features(coroutine_tests PRIVATE cxx_std_20) target_link_libraries(coroutine_tests PRIVATE todaygraphql graphqljson @@ -32,6 +34,7 @@ target_link_libraries(coroutine_tests PRIVATE gtest_add_tests(TARGET coroutine_tests) add_executable(client_tests ClientTests.cpp) +target_compile_features(client_tests PRIVATE cxx_std_20) target_link_libraries(client_tests PRIVATE todaygraphql query_client @@ -43,6 +46,7 @@ add_bigobj_flag(client_tests) gtest_add_tests(TARGET client_tests) add_executable(nointrospection_tests NoIntrospectionTests.cpp) +target_compile_features(nointrospection_tests PRIVATE cxx_std_20) target_link_libraries(nointrospection_tests PRIVATE todaygraphql_nointrospection graphqljson @@ -52,6 +56,7 @@ add_bigobj_flag(nointrospection_tests) gtest_add_tests(TARGET nointrospection_tests) add_executable(argument_tests ArgumentTests.cpp) +target_compile_features(argument_tests PRIVATE cxx_std_20) target_link_libraries(argument_tests PRIVATE todaygraphql graphqljson From 22ed39d7685c2dfa0ef2f8db514d777f49e2fcbd Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 17:53:56 -0700 Subject: [PATCH 043/123] fix(modules): try making lambdas noexcept for GCC mangling --- samples/today/TodayMock.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index e41d2582..af33036e 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -63,33 +63,33 @@ std::unique_ptr mock_service() noexcept auto result = std::make_unique(); auto query = std::make_shared( - [mockService = result.get()]() -> std::vector> { + [mockService = result.get()]() noexcept -> std::vector> { ++mockService->getAppointmentsCount; return { std::make_shared(response::IdType(getFakeAppointmentId()), "tomorrow", "Lunch?", false) }; }, - [mockService = result.get()]() -> std::vector> { + [mockService = result.get()]() noexcept -> std::vector> { ++mockService->getTasksCount; return { std::make_shared(response::IdType(getFakeTaskId()), "Don't forget", true) }; }, - [mockService = result.get()]() -> std::vector> { + [mockService = result.get()]() noexcept -> std::vector> { ++mockService->getUnreadCountsCount; return { std::make_shared(response::IdType(getFakeFolderId()), "\"Fake\" Inbox", 3) }; }); auto mutation = std::make_shared( - [](CompleteTaskInput&& input) -> std::shared_ptr { + [](CompleteTaskInput&& input) noexcept -> std::shared_ptr { return std::make_shared( std::make_shared(std::move(input.id), "Mutated Task!", *(input.isComplete)), std::move(input.clientMutationId)); }); auto subscription = std::make_shared( - [](const std::shared_ptr&) -> std::shared_ptr { + [](const std::shared_ptr&) noexcept -> std::shared_ptr { return { std::make_shared(response::IdType(getFakeAppointmentId()), "tomorrow", "Lunch?", From 5dc0f90e958e35b2b73fc968532727307268ef76 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 18:24:36 -0700 Subject: [PATCH 044/123] fix(gcc): try specifying -fabi-version=0 --- samples/today/CMakeLists.txt | 10 ++++++---- samples/today/TodayMock.cpp | 10 +++++----- test/CMakeLists.txt | 5 ----- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/samples/today/CMakeLists.txt b/samples/today/CMakeLists.txt index 9642b50e..535fa689 100644 --- a/samples/today/CMakeLists.txt +++ b/samples/today/CMakeLists.txt @@ -7,6 +7,9 @@ cmake_minimum_required(VERSION 3.28) add_subdirectory(schema) add_library(todaygraphql STATIC TodayMock.cpp) target_compile_features(todaygraphql PUBLIC cxx_std_20) +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_options(todaygraphql PUBLIC "-fabi-version=0") +endif() target_link_libraries(todaygraphql PUBLIC today_schema) target_sources(todaygraphql PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} @@ -16,6 +19,9 @@ target_sources(todaygraphql PUBLIC FILE_SET CXX_MODULES add_subdirectory(nointrospection) add_library(todaygraphql_nointrospection STATIC TodayMock.cpp) target_compile_features(todaygraphql_nointrospection PUBLIC cxx_std_20) +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_options(todaygraphql_nointrospection PUBLIC "-fabi-version=0") +endif() target_link_libraries(todaygraphql_nointrospection PUBLIC today_nointrospection_schema) target_sources(todaygraphql_nointrospection PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} @@ -29,28 +35,24 @@ endif() # sample add_executable(sample sample.cpp) -target_compile_features(sample PUBLIC cxx_std_20) target_link_libraries(sample PRIVATE todaygraphql graphqljson) # sample_nointrospection add_executable(sample_nointrospection sample.cpp) -target_compile_features(sample_nointrospection PUBLIC cxx_std_20) target_link_libraries(sample_nointrospection PRIVATE todaygraphql_nointrospection graphqljson) # benchmark add_executable(benchmark benchmark.cpp) -target_compile_features(benchmark PUBLIC cxx_std_20) target_link_libraries(benchmark PRIVATE todaygraphql graphqljson) # benchmark_nointrospection add_executable(benchmark_nointrospection benchmark.cpp) -target_compile_features(benchmark_nointrospection PUBLIC cxx_std_20) target_link_libraries(benchmark_nointrospection PRIVATE todaygraphql_nointrospection graphqljson) diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index af33036e..e41d2582 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -63,33 +63,33 @@ std::unique_ptr mock_service() noexcept auto result = std::make_unique(); auto query = std::make_shared( - [mockService = result.get()]() noexcept -> std::vector> { + [mockService = result.get()]() -> std::vector> { ++mockService->getAppointmentsCount; return { std::make_shared(response::IdType(getFakeAppointmentId()), "tomorrow", "Lunch?", false) }; }, - [mockService = result.get()]() noexcept -> std::vector> { + [mockService = result.get()]() -> std::vector> { ++mockService->getTasksCount; return { std::make_shared(response::IdType(getFakeTaskId()), "Don't forget", true) }; }, - [mockService = result.get()]() noexcept -> std::vector> { + [mockService = result.get()]() -> std::vector> { ++mockService->getUnreadCountsCount; return { std::make_shared(response::IdType(getFakeFolderId()), "\"Fake\" Inbox", 3) }; }); auto mutation = std::make_shared( - [](CompleteTaskInput&& input) noexcept -> std::shared_ptr { + [](CompleteTaskInput&& input) -> std::shared_ptr { return std::make_shared( std::make_shared(std::move(input.id), "Mutated Task!", *(input.isComplete)), std::move(input.clientMutationId)); }); auto subscription = std::make_shared( - [](const std::shared_ptr&) noexcept -> std::shared_ptr { + [](const std::shared_ptr&) -> std::shared_ptr { return { std::make_shared(response::IdType(getFakeAppointmentId()), "tomorrow", "Lunch?", diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e845c1ef..9e0a8150 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,7 +15,6 @@ add_bigobj_flag(validation_tests) gtest_add_tests(TARGET validation_tests) add_executable(today_tests TodayTests.cpp) -target_compile_features(today_tests PRIVATE cxx_std_20) target_link_libraries(today_tests PRIVATE todaygraphql graphqljson @@ -25,7 +24,6 @@ add_bigobj_flag(today_tests) gtest_add_tests(TARGET today_tests) add_executable(coroutine_tests CoroutineTests.cpp) -target_compile_features(coroutine_tests PRIVATE cxx_std_20) target_link_libraries(coroutine_tests PRIVATE todaygraphql graphqljson @@ -34,7 +32,6 @@ target_link_libraries(coroutine_tests PRIVATE gtest_add_tests(TARGET coroutine_tests) add_executable(client_tests ClientTests.cpp) -target_compile_features(client_tests PRIVATE cxx_std_20) target_link_libraries(client_tests PRIVATE todaygraphql query_client @@ -46,7 +43,6 @@ add_bigobj_flag(client_tests) gtest_add_tests(TARGET client_tests) add_executable(nointrospection_tests NoIntrospectionTests.cpp) -target_compile_features(nointrospection_tests PRIVATE cxx_std_20) target_link_libraries(nointrospection_tests PRIVATE todaygraphql_nointrospection graphqljson @@ -56,7 +52,6 @@ add_bigobj_flag(nointrospection_tests) gtest_add_tests(TARGET nointrospection_tests) add_executable(argument_tests ArgumentTests.cpp) -target_compile_features(argument_tests PRIVATE cxx_std_20) target_link_libraries(argument_tests PRIVATE todaygraphql graphqljson From de35976d2cf2ae8ba7212d357ba0fc4ce6b6b157 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 13 Sep 2024 18:53:21 -0700 Subject: [PATCH 045/123] fix(gcc): try -fabi-compat-version --- CMakeLists.txt | 5 +++++ samples/today/CMakeLists.txt | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c6440dd..f3cb9a2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,11 @@ else() add_compile_options(-Wall -Wextra -pedantic -Werror) endif() +# Workaround name mangling compatibility in GCC. +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + add_compile_options(-fabi-compat-version=19) +endif() + function(add_bigobj_flag target) if(MSVC) # MSVC requires the /bigobj flag if the number of sections gets too big. diff --git a/samples/today/CMakeLists.txt b/samples/today/CMakeLists.txt index 535fa689..ff5bbace 100644 --- a/samples/today/CMakeLists.txt +++ b/samples/today/CMakeLists.txt @@ -7,9 +7,6 @@ cmake_minimum_required(VERSION 3.28) add_subdirectory(schema) add_library(todaygraphql STATIC TodayMock.cpp) target_compile_features(todaygraphql PUBLIC cxx_std_20) -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - target_compile_options(todaygraphql PUBLIC "-fabi-version=0") -endif() target_link_libraries(todaygraphql PUBLIC today_schema) target_sources(todaygraphql PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} @@ -19,9 +16,6 @@ target_sources(todaygraphql PUBLIC FILE_SET CXX_MODULES add_subdirectory(nointrospection) add_library(todaygraphql_nointrospection STATIC TodayMock.cpp) target_compile_features(todaygraphql_nointrospection PUBLIC cxx_std_20) -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - target_compile_options(todaygraphql_nointrospection PUBLIC "-fabi-version=0") -endif() target_link_libraries(todaygraphql_nointrospection PUBLIC today_nointrospection_schema) target_sources(todaygraphql_nointrospection PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} From 81bf6bc34fb28873c096d194ef575ede8c013c76 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 14 Sep 2024 13:41:16 -0700 Subject: [PATCH 046/123] fix(cmake): ignore CMakeUserPresets.json --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 696df878..08458f10 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ CMakeSettings.json CMakeCache.txt CTestCostData.txt CTestTestfile.cmake +CMakeUserPresets.json DartConfiguration.tcl install_manifest.txt LastTest.log From ec2a29db8dc9f624dc265cb583d948e29202c2ce Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 14 Sep 2024 21:39:44 -0700 Subject: [PATCH 047/123] fix(modules): wrap JSONResponse and TodayMock --- cmake/Version.h.in | 4 + include/graphqlservice/Client.ixx | 28 +- include/graphqlservice/JSONResponse.ixx | 17 + include/graphqlservice/Service.ixx | 56 ++- include/graphqlservice/internal/Version.h | 4 + include/graphqlservice/internal/Version.ixx | 16 +- samples/CMakeLists.txt | 2 +- samples/client/benchmark.cpp | 26 +- samples/today/CMakeLists.txt | 20 +- samples/today/TodayMock.cpp | 16 +- samples/today/TodayMock.h | 415 ++++++++++++++++++ samples/today/TodayMock.ixx | 448 ++------------------ samples/today/benchmark.cpp | 27 +- samples/today/sample.cpp | 29 +- src/CMakeLists.txt | 24 +- test/ClientTests.cpp | 23 + test/CoroutineTests.cpp | 29 +- test/NoIntrospectionTests.cpp | 27 +- test/TodayTests.cpp | 27 +- 19 files changed, 735 insertions(+), 503 deletions(-) create mode 100644 include/graphqlservice/JSONResponse.ixx create mode 100644 samples/today/TodayMock.h diff --git a/cmake/Version.h.in b/cmake/Version.h.in index e2bdc9c8..711f874c 100644 --- a/cmake/Version.h.in +++ b/cmake/Version.h.in @@ -11,12 +11,16 @@ namespace graphql::internal { +inline namespace version { + constexpr std::string_view FullVersion { "@PROJECT_VERSION@" }; constexpr std::size_t MajorVersion = @PROJECT_VERSION_MAJOR@; constexpr std::size_t MinorVersion = @PROJECT_VERSION_MINOR@; constexpr std::size_t PatchVersion = @PROJECT_VERSION_PATCH@; +} // namespace version + } // namespace graphql::internal #endif // GRAPHQLVERSION_H diff --git a/include/graphqlservice/Client.ixx b/include/graphqlservice/Client.ixx index aa3f6814..7db2df94 100644 --- a/include/graphqlservice/Client.ixx +++ b/include/graphqlservice/Client.ixx @@ -18,23 +18,23 @@ using client::parseServiceResponse; using client::TypeModifier; using client::Variable; -using client::ModifiedVariable; -using client::IntVariable; -using client::FloatVariable; -using client::StringVariable; -using client::BooleanVariable; -using client::IdVariable; -using client::ScalarVariable; +using modified_variable::ModifiedVariable; +using modified_variable::IntVariable; +using modified_variable::FloatVariable; +using modified_variable::StringVariable; +using modified_variable::BooleanVariable; +using modified_variable::IdVariable; +using modified_variable::ScalarVariable; using client::Response; -using client::ModifiedResponse; -using client::IntResponse; -using client::FloatResponse; -using client::StringResponse; -using client::BooleanResponse; -using client::IdResponse; -using client::ScalarResponse; +using modified_response::ModifiedResponse; +using modified_response::IntResponse; +using modified_response::FloatResponse; +using modified_response::StringResponse; +using modified_response::BooleanResponse; +using modified_response::IdResponse; +using modified_response::ScalarResponse; // clang-format on } // namespace graphql::client diff --git a/include/graphqlservice/JSONResponse.ixx b/include/graphqlservice/JSONResponse.ixx new file mode 100644 index 00000000..4fc5106d --- /dev/null +++ b/include/graphqlservice/JSONResponse.ixx @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "JSONResponse.h" + +export module GraphQL.JSONResponse; + +export namespace graphql::response { + +// clang-format off +using response::toJSON; +using response::parseJSON; +// clang-format on + +} // namespace graphql::response diff --git a/include/graphqlservice/Service.ixx b/include/graphqlservice/Service.ixx index 1a4429de..62f1380d 100644 --- a/include/graphqlservice/Service.ixx +++ b/include/graphqlservice/Service.ixx @@ -33,22 +33,16 @@ using service::unimplemented_method; using service::RequestState; -namespace constants { - -constexpr std::string_view strData = service::strData; -constexpr std::string_view strErrors = service::strErrors; -constexpr std::string_view strMessage = service::strMessage; -constexpr std::string_view strLocations = service::strLocations; -constexpr std::string_view strLine = service::strLine; -constexpr std::string_view strColumn = service::strColumn; -constexpr std::string_view strPath = service::strPath; -constexpr std::string_view strQuery = service::strQuery; -constexpr std::string_view strMutation = service::strMutation; -constexpr std::string_view strSubscription = service::strSubscription; - -} // namespace constants - -using namespace constants; +constexpr std::string_view strData = keywords::strData; +constexpr std::string_view strErrors = keywords::strErrors; +constexpr std::string_view strMessage = keywords::strMessage; +constexpr std::string_view strLocations = keywords::strLocations; +constexpr std::string_view strLine = keywords::strLine; +constexpr std::string_view strColumn = keywords::strColumn; +constexpr std::string_view strPath = keywords::strPath; +constexpr std::string_view strQuery = keywords::strQuery; +constexpr std::string_view strMutation = keywords::strMutation; +constexpr std::string_view strSubscription = keywords::strSubscription; using service::ResolverContext; @@ -78,26 +72,26 @@ using service::ResolverMap; using service::TypeModifier; using service::Argument; -using service::ModifiedArgument; -using service::IntArgument; -using service::FloatArgument; -using service::StringArgument; -using service::BooleanArgument; -using service::IdArgument; -using service::ScalarArgument; +using modified_argument::ModifiedArgument; +using modified_argument::IntArgument; +using modified_argument::FloatArgument; +using modified_argument::StringArgument; +using modified_argument::BooleanArgument; +using modified_argument::IdArgument; +using modified_argument::ScalarArgument; using service::TypeNames; using service::Object; using service::Result; -using service::ModifiedResult; -using service::IntResult; -using service::FloatResult; -using service::StringResult; -using service::BooleanResult; -using service::IdResult; -using service::ScalarResult; -using service::ObjectResult; +using modified_result::ModifiedResult; +using modified_result::IntResult; +using modified_result::FloatResult; +using modified_result::StringResult; +using modified_result::BooleanResult; +using modified_result::IdResult; +using modified_result::ScalarResult; +using modified_result::ObjectResult; using service::SubscriptionCallback; using service::SubscriptionKey; diff --git a/include/graphqlservice/internal/Version.h b/include/graphqlservice/internal/Version.h index 2384ae15..8691f3b4 100644 --- a/include/graphqlservice/internal/Version.h +++ b/include/graphqlservice/internal/Version.h @@ -11,12 +11,16 @@ namespace graphql::internal { +inline namespace version { + constexpr std::string_view FullVersion { "4.5.8" }; constexpr std::size_t MajorVersion = 4; constexpr std::size_t MinorVersion = 5; constexpr std::size_t PatchVersion = 8; +} // namespace version + } // namespace graphql::internal #endif // GRAPHQLVERSION_H diff --git a/include/graphqlservice/internal/Version.ixx b/include/graphqlservice/internal/Version.ixx index a763b98c..5fd825f0 100644 --- a/include/graphqlservice/internal/Version.ixx +++ b/include/graphqlservice/internal/Version.ixx @@ -9,16 +9,12 @@ export module GraphQL.Internal.Version; export namespace graphql::internal { -namespace constants { +// clang-format off +constexpr std::string_view FullVersion = version::FullVersion; -constexpr std::string_view FullVersion = internal::FullVersion; - -constexpr std::size_t MajorVersion = internal::MajorVersion; -constexpr std::size_t MinorVersion = internal::MinorVersion; -constexpr std::size_t PatchVersion = internal::PatchVersion; - -} // namespace constants - -using namespace constants; +constexpr std::size_t MajorVersion = version::MajorVersion; +constexpr std::size_t MinorVersion = version::MinorVersion; +constexpr std::size_t PatchVersion = version::PatchVersion; +// clang-format on } // namespace graphql::internal diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 99131474..0fcbfacf 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -9,7 +9,7 @@ add_subdirectory(today) add_subdirectory(validation) if(GRAPHQL_BUILD_HTTP_SAMPLE) - find_package(Boost QUIET) + find_package(boost_beast CONFIG QUIET) if(Boost_FOUND) if(Boost_VERSION VERSION_GREATER_EQUAL "1.81.0") try_compile(TEST_RESULT diff --git a/samples/client/benchmark.cpp b/samples/client/benchmark.cpp index d8a8d79e..ba959aa6 100644 --- a/samples/client/benchmark.cpp +++ b/samples/client/benchmark.cpp @@ -12,9 +12,33 @@ #include import GraphQL.Client; -import GraphQL.Parse; +import GraphQL.Response; +import GraphQL.Service; + +import GraphQL.Today.TodaySchema; + +import GraphQL.Today.QueryObject; +import GraphQL.Today.MutationObject; +import GraphQL.Today.SubscriptionObject; + +import GraphQL.Today.AppointmentEdgeObject; +import GraphQL.Today.AppointmentObject; +import GraphQL.Today.AppointmentConnectionObject; +import GraphQL.Today.CompleteTaskPayloadObject; +import GraphQL.Today.ExpensiveObject; +import GraphQL.Today.FolderEdgeObject; +import GraphQL.Today.FolderObject; +import GraphQL.Today.FolderConnectionObject; +import GraphQL.Today.NestedTypeObject; +import GraphQL.Today.NodeObject; +import GraphQL.Today.PageInfoObject; +import GraphQL.Today.TaskConnectionObject; +import GraphQL.Today.TaskEdgeObject; +import GraphQL.Today.TaskObject; +import GraphQL.Today.UnionTypeObject; import GraphQL.Today.Mock; + import GraphQL.Benchmark.BenchmarkClient; using namespace graphql; diff --git a/samples/today/CMakeLists.txt b/samples/today/CMakeLists.txt index ff5bbace..e8b1e5b0 100644 --- a/samples/today/CMakeLists.txt +++ b/samples/today/CMakeLists.txt @@ -8,18 +8,26 @@ add_subdirectory(schema) add_library(todaygraphql STATIC TodayMock.cpp) target_compile_features(todaygraphql PUBLIC cxx_std_20) target_link_libraries(todaygraphql PUBLIC today_schema) -target_sources(todaygraphql PUBLIC FILE_SET CXX_MODULES - BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} - FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.ixx) +target_sources(todaygraphql + PUBLIC FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.h + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.ixx) # todaygraphql_nointrospection add_subdirectory(nointrospection) add_library(todaygraphql_nointrospection STATIC TodayMock.cpp) target_compile_features(todaygraphql_nointrospection PUBLIC cxx_std_20) target_link_libraries(todaygraphql_nointrospection PUBLIC today_nointrospection_schema) -target_sources(todaygraphql_nointrospection PUBLIC FILE_SET CXX_MODULES - BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} - FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.ixx) +target_sources(todaygraphql_nointrospection + PUBLIC FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.h + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.ixx) if(MSVC) # warning C4702: unreachable code diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index e41d2582..53b0b35b 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -1,18 +1,20 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -module; +#include "TodayMock.h" + +#include "AppointmentConnectionObject.h" +#include "CompleteTaskPayloadObject.h" +#include "ExpensiveObject.h" +#include "FolderConnectionObject.h" +#include "NestedTypeObject.h" +#include "TaskConnectionObject.h" +#include "UnionTypeObject.h" #include #include -#include -#include #include #include -#include -#include - -module GraphQL.Today.Mock; namespace graphql::today { diff --git a/samples/today/TodayMock.h b/samples/today/TodayMock.h new file mode 100644 index 00000000..60f97fa1 --- /dev/null +++ b/samples/today/TodayMock.h @@ -0,0 +1,415 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#ifndef TODAYMOCK_H +#define TODAYMOCK_H + +#include "TodaySchema.h" + +#include "AppointmentEdgeObject.h" +#include "AppointmentObject.h" +#include "FolderEdgeObject.h" +#include "FolderObject.h" +#include "MutationObject.h" +#include "NodeObject.h" +#include "PageInfoObject.h" +#include "QueryObject.h" +#include "SubscriptionObject.h" +#include "TaskEdgeObject.h" +#include "TaskObject.h" + +#include +#include +#include + +namespace graphql::today { + +// These IDs are hard-coded in every test which uses TodayMock. +const response::IdType& getFakeAppointmentId() noexcept; +const response::IdType& getFakeTaskId() noexcept; +const response::IdType& getFakeFolderId() noexcept; + +struct TodayMockService +{ + std::shared_ptr service {}; + std::size_t getAppointmentsCount {}; + std::size_t getTasksCount {}; + std::size_t getUnreadCountsCount {}; +}; + +std::unique_ptr mock_service() noexcept; + +struct RequestState : service::RequestState +{ + RequestState(std::size_t id); + + const std::size_t requestId; + + std::size_t appointmentsRequestId = 0; + std::size_t tasksRequestId = 0; + std::size_t unreadCountsRequestId = 0; + + std::size_t loadAppointmentsCount = 0; + std::size_t loadTasksCount = 0; + std::size_t loadUnreadCountsCount = 0; +}; + +class Appointment; +class Task; +class Folder; +class Expensive; + +class Query : public std::enable_shared_from_this +{ +public: + using appointmentsLoader = std::function>()>; + using tasksLoader = std::function>()>; + using unreadCountsLoader = std::function>()>; + + explicit Query(appointmentsLoader&& getAppointments, tasksLoader&& getTasks, + unreadCountsLoader&& getUnreadCounts); + + service::AwaitableObject> getNode( + service::FieldParams params, response::IdType id); + std::future> getAppointments( + const service::FieldParams& params, std::optional first, + std::optional&& after, std::optional last, + std::optional&& before); + std::future> getTasks( + const service::FieldParams& params, std::optional first, + std::optional&& after, std::optional last, + std::optional&& before); + std::future> getUnreadCounts( + const service::FieldParams& params, std::optional first, + std::optional&& after, std::optional last, + std::optional&& before); + std::vector> getAppointmentsById( + const service::FieldParams& params, const std::vector& ids); + std::vector> getTasksById( + const service::FieldParams& params, const std::vector& ids); + std::vector> getUnreadCountsById( + const service::FieldParams& params, const std::vector& ids); + std::shared_ptr getNested(service::FieldParams&& params); + std::vector> getExpensive(); + TaskState getTestTaskState(); + std::vector> getAnyType( + const service::FieldParams& params, const std::vector& ids); + std::optional getDefault() const noexcept; + +private: + std::shared_ptr findAppointment( + const service::FieldParams& params, const response::IdType& id); + std::shared_ptr findTask(const service::FieldParams& params, const response::IdType& id); + std::shared_ptr findUnreadCount( + const service::FieldParams& params, const response::IdType& id); + + // Lazy load the fields in each query + void loadAppointments(const std::shared_ptr& state); + void loadTasks(const std::shared_ptr& state); + void loadUnreadCounts(const std::shared_ptr& state); + + appointmentsLoader _getAppointments; + tasksLoader _getTasks; + unreadCountsLoader _getUnreadCounts; + + std::vector> _appointments; + std::vector> _tasks; + std::vector> _unreadCounts; +}; + +class PageInfo +{ +public: + explicit PageInfo(bool hasNextPage, bool hasPreviousPage); + + bool getHasNextPage() const noexcept; + bool getHasPreviousPage() const noexcept; + +private: + const bool _hasNextPage; + const bool _hasPreviousPage; +}; + +class Appointment +{ +public: + explicit Appointment( + response::IdType&& id, std::string&& when, std::string&& subject, bool isNow); + + // EdgeConstraints accessor + const response::IdType& id() const noexcept; + + service::AwaitableScalar getId() const noexcept; + std::shared_ptr getWhen() const noexcept; + std::shared_ptr getSubject() const noexcept; + bool getIsNow() const noexcept; + std::optional getForceError() const; + +private: + response::IdType _id; + std::shared_ptr _when; + std::shared_ptr _subject; + bool _isNow; +}; + +class AppointmentEdge +{ +public: + explicit AppointmentEdge(std::shared_ptr appointment); + + std::shared_ptr getNode() const noexcept; + service::AwaitableScalar getCursor() const; + +private: + std::shared_ptr _appointment; +}; + +class AppointmentConnection +{ +public: + explicit AppointmentConnection(bool hasNextPage, bool hasPreviousPage, + std::vector> appointments); + + std::shared_ptr getPageInfo() const noexcept; + std::optional>> getEdges() const noexcept; + +private: + std::shared_ptr _pageInfo; + std::vector> _appointments; +}; + +class Task +{ +public: + explicit Task(response::IdType&& id, std::string&& title, bool isComplete); + + // EdgeConstraints accessor + const response::IdType& id() const; + + service::AwaitableScalar getId() const noexcept; + std::shared_ptr getTitle() const noexcept; + bool getIsComplete() const noexcept; + +private: + response::IdType _id; + std::shared_ptr _title; + bool _isComplete; +}; + +class TaskEdge +{ +public: + explicit TaskEdge(std::shared_ptr task); + + std::shared_ptr getNode() const noexcept; + service::AwaitableScalar getCursor() const noexcept; + +private: + std::shared_ptr _task; +}; + +class TaskConnection +{ +public: + explicit TaskConnection( + bool hasNextPage, bool hasPreviousPage, std::vector> tasks); + + std::shared_ptr getPageInfo() const noexcept; + std::optional>> getEdges() const noexcept; + +private: + std::shared_ptr _pageInfo; + std::vector> _tasks; +}; + +class Folder +{ +public: + explicit Folder(response::IdType&& id, std::string&& name, int unreadCount); + + // EdgeConstraints accessor + const response::IdType& id() const noexcept; + + service::AwaitableScalar getId() const noexcept; + std::shared_ptr getName() const noexcept; + int getUnreadCount() const noexcept; + +private: + response::IdType _id; + std::shared_ptr _name; + int _unreadCount; +}; + +class FolderEdge +{ +public: + explicit FolderEdge(std::shared_ptr folder); + + std::shared_ptr getNode() const noexcept; + service::AwaitableScalar getCursor() const noexcept; + +private: + std::shared_ptr _folder; +}; + +class FolderConnection +{ +public: + explicit FolderConnection( + bool hasNextPage, bool hasPreviousPage, std::vector> folders); + + std::shared_ptr getPageInfo() const noexcept; + std::optional>> getEdges() const noexcept; + +private: + std::shared_ptr _pageInfo; + std::vector> _folders; +}; + +class CompleteTaskPayload +{ +public: + explicit CompleteTaskPayload( + std::shared_ptr task, std::optional&& clientMutationId); + + std::shared_ptr getTask() const noexcept; + const std::optional& getClientMutationId() const noexcept; + +private: + std::shared_ptr _task; + std::optional _clientMutationId; +}; + +class Mutation +{ +public: + using completeTaskMutation = + std::function(CompleteTaskInput&&)>; + + explicit Mutation(completeTaskMutation&& mutateCompleteTask); + + static double getFloat() noexcept; + + std::shared_ptr applyCompleteTask( + CompleteTaskInput&& input) noexcept; + double applySetFloat(double valueArg) noexcept; + +private: + completeTaskMutation _mutateCompleteTask; + static std::optional _setFloat; +}; + +class Subscription +{ +public: + explicit Subscription() = default; + + std::shared_ptr getNextAppointmentChange() const; + std::shared_ptr getNodeChange(const response::IdType&) const; +}; + +class NextAppointmentChange +{ +public: + using nextAppointmentChange = + std::function(const std::shared_ptr&)>; + + explicit NextAppointmentChange(nextAppointmentChange&& changeNextAppointment); + + static std::size_t getCount(service::ResolverContext resolverContext); + + std::shared_ptr getNextAppointmentChange( + const service::FieldParams& params) const; + std::shared_ptr getNodeChange(const response::IdType&) const; + +private: + nextAppointmentChange _changeNextAppointment; + + static std::size_t _notifySubscribeCount; + static std::size_t _subscriptionCount; + static std::size_t _notifyUnsubscribeCount; +}; + +class NodeChange +{ +public: + using nodeChange = + std::function(service::ResolverContext resolverContext, + const std::shared_ptr&, response::IdType&&)>; + + explicit NodeChange(nodeChange&& changeNode); + + std::shared_ptr getNextAppointmentChange() const; + std::shared_ptr getNodeChange( + const service::FieldParams& params, response::IdType&& idArg) const; + +private: + nodeChange _changeNode; +}; + +struct CapturedParams +{ + // Copied in the constructor + const service::Directives operationDirectives; + const service::Directives fragmentDefinitionDirectives; + const service::Directives fragmentSpreadDirectives; + const service::Directives inlineFragmentDirectives; + + // Moved in the constructor + const service::Directives fieldDirectives; +}; + +class NestedType +{ +public: + explicit NestedType(service::FieldParams&& params, int depth); + + int getDepth() const noexcept; + std::shared_ptr getNested(service::FieldParams&& params) const noexcept; + + static std::stack getCapturedParams() noexcept; + +private: + static std::stack _capturedParams; + + // Initialized in the constructor + const int depth; +}; + +class Expensive +{ +public: + static bool Reset() noexcept; + + explicit Expensive(); + ~Expensive(); + + std::future getOrder(const service::FieldParams& params) const noexcept; + + static constexpr std::size_t count = 5; + static std::mutex testMutex; + +private: + // Block async calls to getOrder until pendingExpensive == count + static std::mutex pendingExpensiveMutex; + static std::condition_variable pendingExpensiveCondition; + static std::size_t pendingExpensive; + + // Number of instances + static std::atomic instances; + + // Initialized in the constructor + const std::size_t order; +}; + +class EmptyOperations : public service::Request +{ +public: + explicit EmptyOperations(); +}; + +} // namespace graphql::today + +#endif // TODAYMOCK_H diff --git a/samples/today/TodayMock.ixx b/samples/today/TodayMock.ixx index 2a4af79f..f8142989 100644 --- a/samples/today/TodayMock.ixx +++ b/samples/today/TodayMock.ixx @@ -3,426 +3,42 @@ module; -#include -#include -#include -#include -#include -#include -#include -#include +#include "TodayMock.h" export module GraphQL.Today.Mock; -export import GraphQL.Response; -export import GraphQL.Service; - -export import GraphQL.Today.TodaySchema; - -export import GraphQL.Today.QueryObject; -export import GraphQL.Today.MutationObject; -export import GraphQL.Today.SubscriptionObject; - -export import GraphQL.Today.AppointmentEdgeObject; -export import GraphQL.Today.AppointmentObject; -export import GraphQL.Today.AppointmentConnectionObject; -export import GraphQL.Today.CompleteTaskPayloadObject; -export import GraphQL.Today.ExpensiveObject; -export import GraphQL.Today.FolderEdgeObject; -export import GraphQL.Today.FolderObject; -export import GraphQL.Today.FolderConnectionObject; -export import GraphQL.Today.NestedTypeObject; -export import GraphQL.Today.NodeObject; -export import GraphQL.Today.PageInfoObject; -export import GraphQL.Today.TaskConnectionObject; -export import GraphQL.Today.TaskEdgeObject; -export import GraphQL.Today.TaskObject; -export import GraphQL.Today.UnionTypeObject; - export namespace graphql::today { -// These IDs are hard-coded in every test which uses TodayMock. -const response::IdType& getFakeAppointmentId() noexcept; -const response::IdType& getFakeTaskId() noexcept; -const response::IdType& getFakeFolderId() noexcept; - -struct TodayMockService -{ - std::shared_ptr service {}; - std::size_t getAppointmentsCount {}; - std::size_t getTasksCount {}; - std::size_t getUnreadCountsCount {}; -}; - -std::unique_ptr mock_service() noexcept; - -struct RequestState : service::RequestState -{ - RequestState(std::size_t id); - - const std::size_t requestId; - - std::size_t appointmentsRequestId = 0; - std::size_t tasksRequestId = 0; - std::size_t unreadCountsRequestId = 0; - - std::size_t loadAppointmentsCount = 0; - std::size_t loadTasksCount = 0; - std::size_t loadUnreadCountsCount = 0; -}; - -class Appointment; -class Task; -class Folder; -class Expensive; - -class Query : public std::enable_shared_from_this -{ -public: - using appointmentsLoader = std::function>()>; - using tasksLoader = std::function>()>; - using unreadCountsLoader = std::function>()>; - - explicit Query(appointmentsLoader&& getAppointments, tasksLoader&& getTasks, - unreadCountsLoader&& getUnreadCounts); - - service::AwaitableObject> getNode( - service::FieldParams params, response::IdType id); - std::future> getAppointments( - const service::FieldParams& params, std::optional first, - std::optional&& after, std::optional last, - std::optional&& before); - std::future> getTasks( - const service::FieldParams& params, std::optional first, - std::optional&& after, std::optional last, - std::optional&& before); - std::future> getUnreadCounts( - const service::FieldParams& params, std::optional first, - std::optional&& after, std::optional last, - std::optional&& before); - std::vector> getAppointmentsById( - const service::FieldParams& params, const std::vector& ids); - std::vector> getTasksById( - const service::FieldParams& params, const std::vector& ids); - std::vector> getUnreadCountsById( - const service::FieldParams& params, const std::vector& ids); - std::shared_ptr getNested(service::FieldParams&& params); - std::vector> getExpensive(); - TaskState getTestTaskState(); - std::vector> getAnyType( - const service::FieldParams& params, const std::vector& ids); - std::optional getDefault() const noexcept; - -private: - std::shared_ptr findAppointment( - const service::FieldParams& params, const response::IdType& id); - std::shared_ptr findTask(const service::FieldParams& params, const response::IdType& id); - std::shared_ptr findUnreadCount( - const service::FieldParams& params, const response::IdType& id); - - // Lazy load the fields in each query - void loadAppointments(const std::shared_ptr& state); - void loadTasks(const std::shared_ptr& state); - void loadUnreadCounts(const std::shared_ptr& state); - - appointmentsLoader _getAppointments; - tasksLoader _getTasks; - unreadCountsLoader _getUnreadCounts; - - std::vector> _appointments; - std::vector> _tasks; - std::vector> _unreadCounts; -}; - -class PageInfo -{ -public: - explicit PageInfo(bool hasNextPage, bool hasPreviousPage); - - bool getHasNextPage() const noexcept; - bool getHasPreviousPage() const noexcept; - -private: - const bool _hasNextPage; - const bool _hasPreviousPage; -}; - -class Appointment -{ -public: - explicit Appointment( - response::IdType&& id, std::string&& when, std::string&& subject, bool isNow); - - // EdgeConstraints accessor - const response::IdType& id() const noexcept; - - service::AwaitableScalar getId() const noexcept; - std::shared_ptr getWhen() const noexcept; - std::shared_ptr getSubject() const noexcept; - bool getIsNow() const noexcept; - std::optional getForceError() const; - -private: - response::IdType _id; - std::shared_ptr _when; - std::shared_ptr _subject; - bool _isNow; -}; - -class AppointmentEdge -{ -public: - explicit AppointmentEdge(std::shared_ptr appointment); - - std::shared_ptr getNode() const noexcept; - service::AwaitableScalar getCursor() const; - -private: - std::shared_ptr _appointment; -}; - -class AppointmentConnection -{ -public: - explicit AppointmentConnection(bool hasNextPage, bool hasPreviousPage, - std::vector> appointments); - - std::shared_ptr getPageInfo() const noexcept; - std::optional>> getEdges() const noexcept; - -private: - std::shared_ptr _pageInfo; - std::vector> _appointments; -}; - -class Task -{ -public: - explicit Task(response::IdType&& id, std::string&& title, bool isComplete); - - // EdgeConstraints accessor - const response::IdType& id() const; - - service::AwaitableScalar getId() const noexcept; - std::shared_ptr getTitle() const noexcept; - bool getIsComplete() const noexcept; - -private: - response::IdType _id; - std::shared_ptr _title; - bool _isComplete; -}; - -class TaskEdge -{ -public: - explicit TaskEdge(std::shared_ptr task); - - std::shared_ptr getNode() const noexcept; - service::AwaitableScalar getCursor() const noexcept; - -private: - std::shared_ptr _task; -}; - -class TaskConnection -{ -public: - explicit TaskConnection( - bool hasNextPage, bool hasPreviousPage, std::vector> tasks); - - std::shared_ptr getPageInfo() const noexcept; - std::optional>> getEdges() const noexcept; - -private: - std::shared_ptr _pageInfo; - std::vector> _tasks; -}; - -class Folder -{ -public: - explicit Folder(response::IdType&& id, std::string&& name, int unreadCount); - - // EdgeConstraints accessor - const response::IdType& id() const noexcept; - - service::AwaitableScalar getId() const noexcept; - std::shared_ptr getName() const noexcept; - int getUnreadCount() const noexcept; - -private: - response::IdType _id; - std::shared_ptr _name; - int _unreadCount; -}; - -class FolderEdge -{ -public: - explicit FolderEdge(std::shared_ptr folder); - - std::shared_ptr getNode() const noexcept; - service::AwaitableScalar getCursor() const noexcept; - -private: - std::shared_ptr _folder; -}; - -class FolderConnection -{ -public: - explicit FolderConnection( - bool hasNextPage, bool hasPreviousPage, std::vector> folders); - - std::shared_ptr getPageInfo() const noexcept; - std::optional>> getEdges() const noexcept; - -private: - std::shared_ptr _pageInfo; - std::vector> _folders; -}; - -class CompleteTaskPayload -{ -public: - explicit CompleteTaskPayload( - std::shared_ptr task, std::optional&& clientMutationId); - - std::shared_ptr getTask() const noexcept; - const std::optional& getClientMutationId() const noexcept; - -private: - std::shared_ptr _task; - std::optional _clientMutationId; -}; - -class Mutation -{ -public: - using completeTaskMutation = - std::function(CompleteTaskInput&&)>; - - explicit Mutation(completeTaskMutation&& mutateCompleteTask); - - static double getFloat() noexcept; - - std::shared_ptr applyCompleteTask( - CompleteTaskInput&& input) noexcept; - double applySetFloat(double valueArg) noexcept; - -private: - completeTaskMutation _mutateCompleteTask; - static std::optional _setFloat; -}; - -class Subscription -{ -public: - explicit Subscription() = default; - - std::shared_ptr getNextAppointmentChange() const; - std::shared_ptr getNodeChange(const response::IdType&) const; -}; - -class NextAppointmentChange -{ -public: - using nextAppointmentChange = - std::function(const std::shared_ptr&)>; - - explicit NextAppointmentChange(nextAppointmentChange&& changeNextAppointment); - - static std::size_t getCount(service::ResolverContext resolverContext); - - std::shared_ptr getNextAppointmentChange( - const service::FieldParams& params) const; - std::shared_ptr getNodeChange(const response::IdType&) const; - -private: - nextAppointmentChange _changeNextAppointment; - - static std::size_t _notifySubscribeCount; - static std::size_t _subscriptionCount; - static std::size_t _notifyUnsubscribeCount; -}; - -class NodeChange -{ -public: - using nodeChange = - std::function(service::ResolverContext resolverContext, - const std::shared_ptr&, response::IdType&&)>; - - explicit NodeChange(nodeChange&& changeNode); - - std::shared_ptr getNextAppointmentChange() const; - std::shared_ptr getNodeChange( - const service::FieldParams& params, response::IdType&& idArg) const; - -private: - nodeChange _changeNode; -}; - -struct CapturedParams -{ - // Copied in the constructor - const service::Directives operationDirectives; - const service::Directives fragmentDefinitionDirectives; - const service::Directives fragmentSpreadDirectives; - const service::Directives inlineFragmentDirectives; - - // Moved in the constructor - const service::Directives fieldDirectives; -}; - -class NestedType -{ -public: - explicit NestedType(service::FieldParams&& params, int depth); - - int getDepth() const noexcept; - std::shared_ptr getNested(service::FieldParams&& params) const noexcept; - - static std::stack getCapturedParams() noexcept; - -private: - static std::stack _capturedParams; - - // Initialized in the constructor - const int depth; -}; - -class Expensive -{ -public: - static bool Reset() noexcept; - - explicit Expensive(); - ~Expensive(); - - std::future getOrder(const service::FieldParams& params) const noexcept; - - static constexpr std::size_t count = 5; - static std::mutex testMutex; - -private: - // Block async calls to getOrder until pendingExpensive == count - static std::mutex pendingExpensiveMutex; - static std::condition_variable pendingExpensiveCondition; - static std::size_t pendingExpensive; - - // Number of instances - static std::atomic instances; - - // Initialized in the constructor - const std::size_t order; -}; - -class EmptyOperations : public service::Request -{ -public: - explicit EmptyOperations(); -}; +// clang-format off +using today::getFakeAppointmentId; +using today::getFakeTaskId; +using today::getFakeFolderId; + +using today::TodayMockService; +using today::mock_service; + +using today::RequestState; + +using today::Query; + +using today::PageInfo; +using today::Appointment; +using today::AppointmentEdge; +using today::Task; +using today::TaskEdge; +using today::TaskConnection; +using today::Folder; +using today::FolderEdge; +using today::FolderConnection; +using today::CompleteTaskPayload; +using today::Mutation; +using today::Subscription; +using today::NextAppointmentChange; +using today::NodeChange; +using today::CapturedParams; +using today::NestedType; +using today::Expensive; +using today::EmptyOperations; +// clang-format on } // namespace graphql::today diff --git a/samples/today/benchmark.cpp b/samples/today/benchmark.cpp index 168563d6..b1c7f7dd 100644 --- a/samples/today/benchmark.cpp +++ b/samples/today/benchmark.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "graphqlservice/JSONResponse.h" - #include #include #include @@ -13,6 +11,31 @@ #include import GraphQL.Parse; +import GraphQL.Response; +import GraphQL.JSONResponse; +import GraphQL.Service; + +import GraphQL.Today.TodaySchema; + +import GraphQL.Today.QueryObject; +import GraphQL.Today.MutationObject; +import GraphQL.Today.SubscriptionObject; + +import GraphQL.Today.AppointmentEdgeObject; +import GraphQL.Today.AppointmentObject; +import GraphQL.Today.AppointmentConnectionObject; +import GraphQL.Today.CompleteTaskPayloadObject; +import GraphQL.Today.ExpensiveObject; +import GraphQL.Today.FolderEdgeObject; +import GraphQL.Today.FolderObject; +import GraphQL.Today.FolderConnectionObject; +import GraphQL.Today.NestedTypeObject; +import GraphQL.Today.NodeObject; +import GraphQL.Today.PageInfoObject; +import GraphQL.Today.TaskConnectionObject; +import GraphQL.Today.TaskEdgeObject; +import GraphQL.Today.TaskObject; +import GraphQL.Today.UnionTypeObject; import GraphQL.Today.Mock; diff --git a/samples/today/sample.cpp b/samples/today/sample.cpp index e665d0ba..5f91c550 100644 --- a/samples/today/sample.cpp +++ b/samples/today/sample.cpp @@ -1,14 +1,37 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "graphqlservice/JSONResponse.h" - #include #include #include #include import GraphQL.Parse; +import GraphQL.Response; +import GraphQL.JSONResponse; +import GraphQL.Service; + +import GraphQL.Today.TodaySchema; + +import GraphQL.Today.QueryObject; +import GraphQL.Today.MutationObject; +import GraphQL.Today.SubscriptionObject; + +import GraphQL.Today.AppointmentEdgeObject; +import GraphQL.Today.AppointmentObject; +import GraphQL.Today.AppointmentConnectionObject; +import GraphQL.Today.CompleteTaskPayloadObject; +import GraphQL.Today.ExpensiveObject; +import GraphQL.Today.FolderEdgeObject; +import GraphQL.Today.FolderObject; +import GraphQL.Today.FolderConnectionObject; +import GraphQL.Today.NestedTypeObject; +import GraphQL.Today.NodeObject; +import GraphQL.Today.PageInfoObject; +import GraphQL.Today.TaskConnectionObject; +import GraphQL.Today.TaskEdgeObject; +import GraphQL.Today.TaskObject; +import GraphQL.Today.UnionTypeObject; import GraphQL.Today.Mock; @@ -16,7 +39,7 @@ using namespace graphql; int main(int argc, char** argv) { - const auto mockService = today::mock_service(); + const auto mockService = graphql::today::mock_service(); const auto& service = mockService->service; std::cout << "Created the service..." << std::endl; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4862ae6a..8b6b484f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -379,7 +379,7 @@ if(GRAPHQL_BUILD_SCHEMAGEN OR GRAPHQL_BUILD_CLIENTGEN) # c++fs check_filesystem_impl("stdc++fs;c++fs" STD_FILESYTEM) - find_package(Boost QUIET REQUIRED COMPONENTS program_options) + find_package(boost_program_options CONFIG REQUIRED) if(GRAPHQL_BUILD_SCHEMAGEN) target_link_libraries(schemagen PRIVATE Boost::program_options) endif() @@ -485,6 +485,17 @@ if(GRAPHQL_USE_RAPIDJSON) target_compile_features(graphqljson PUBLIC cxx_std_20) target_link_libraries(graphqljson PUBLIC graphqlresponse) target_include_directories(graphqljson SYSTEM PRIVATE ${RAPIDJSON_INCLUDE_DIRS}) + target_sources(graphqljson + PUBLIC FILE_SET HEADERS + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/JSONResponse.h + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/JSONResponse.ixx) if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqljson) @@ -537,10 +548,13 @@ if(BUILD_GRAPHQLJSON) EXPORT cppgraphqlgen-targets RUNTIME DESTINATION bin ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/JSONResponse.h - CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} - DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}/graphqlservice) + LIBRARY DESTINATION lib + FILE_SET HEADERS + CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} + DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR} + FILE_SET CXX_MODULES + CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} + DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}) else() set(GRAPHQL_BUILD_TESTS OFF CACHE BOOL "GRAPHQL_BUILD_TESTS depends on BUILD_GRAPHQLJSON" FORCE) endif() diff --git a/test/ClientTests.cpp b/test/ClientTests.cpp index db52176f..647ac109 100644 --- a/test/ClientTests.cpp +++ b/test/ClientTests.cpp @@ -10,11 +10,34 @@ import GraphQL.Parse; import GraphQL.Response; import GraphQL.Client; +import GraphQL.Service; import GraphQL.Mutate.MutateClient; import GraphQL.Query.QueryClient; import GraphQL.Subscribe.SubscribeClient; +import GraphQL.Today.TodaySchema; + +import GraphQL.Today.QueryObject; +import GraphQL.Today.MutationObject; +import GraphQL.Today.SubscriptionObject; + +import GraphQL.Today.AppointmentEdgeObject; +import GraphQL.Today.AppointmentObject; +import GraphQL.Today.AppointmentConnectionObject; +import GraphQL.Today.CompleteTaskPayloadObject; +import GraphQL.Today.ExpensiveObject; +import GraphQL.Today.FolderEdgeObject; +import GraphQL.Today.FolderObject; +import GraphQL.Today.FolderConnectionObject; +import GraphQL.Today.NestedTypeObject; +import GraphQL.Today.NodeObject; +import GraphQL.Today.PageInfoObject; +import GraphQL.Today.TaskConnectionObject; +import GraphQL.Today.TaskEdgeObject; +import GraphQL.Today.TaskObject; +import GraphQL.Today.UnionTypeObject; + import GraphQL.Today.Mock; using namespace graphql; diff --git a/test/CoroutineTests.cpp b/test/CoroutineTests.cpp index e7b51f45..4cea58ea 100644 --- a/test/CoroutineTests.cpp +++ b/test/CoroutineTests.cpp @@ -3,13 +3,36 @@ #include -#include "graphqlservice/JSONResponse.h" - +#include #include import GraphQL.Parse; +import GraphQL.Response; +import GraphQL.JSONResponse; import GraphQL.Service; +import GraphQL.Today.TodaySchema; + +import GraphQL.Today.QueryObject; +import GraphQL.Today.MutationObject; +import GraphQL.Today.SubscriptionObject; + +import GraphQL.Today.AppointmentEdgeObject; +import GraphQL.Today.AppointmentObject; +import GraphQL.Today.AppointmentConnectionObject; +import GraphQL.Today.CompleteTaskPayloadObject; +import GraphQL.Today.ExpensiveObject; +import GraphQL.Today.FolderEdgeObject; +import GraphQL.Today.FolderObject; +import GraphQL.Today.FolderConnectionObject; +import GraphQL.Today.NestedTypeObject; +import GraphQL.Today.NodeObject; +import GraphQL.Today.PageInfoObject; +import GraphQL.Today.TaskConnectionObject; +import GraphQL.Today.TaskEdgeObject; +import GraphQL.Today.TaskObject; +import GraphQL.Today.UnionTypeObject; + import GraphQL.Today.Mock; using namespace graphql; @@ -30,7 +53,7 @@ class CoroutineCase : public ::testing::Test } protected: - std::unique_ptr _mockService; + std::unique_ptr _mockService; }; TEST_F(CoroutineCase, QueryEverythingSync) diff --git a/test/NoIntrospectionTests.cpp b/test/NoIntrospectionTests.cpp index d09cf9cc..b19cd1c6 100644 --- a/test/NoIntrospectionTests.cpp +++ b/test/NoIntrospectionTests.cpp @@ -3,14 +3,37 @@ #include -#include "graphqlservice/JSONResponse.h" - #include #include +#include import GraphQL.Parse; +import GraphQL.Response; +import GraphQL.JSONResponse; import GraphQL.Service; +import GraphQL.Today.TodaySchema; + +import GraphQL.Today.QueryObject; +import GraphQL.Today.MutationObject; +import GraphQL.Today.SubscriptionObject; + +import GraphQL.Today.AppointmentEdgeObject; +import GraphQL.Today.AppointmentObject; +import GraphQL.Today.AppointmentConnectionObject; +import GraphQL.Today.CompleteTaskPayloadObject; +import GraphQL.Today.ExpensiveObject; +import GraphQL.Today.FolderEdgeObject; +import GraphQL.Today.FolderObject; +import GraphQL.Today.FolderConnectionObject; +import GraphQL.Today.NestedTypeObject; +import GraphQL.Today.NodeObject; +import GraphQL.Today.PageInfoObject; +import GraphQL.Today.TaskConnectionObject; +import GraphQL.Today.TaskEdgeObject; +import GraphQL.Today.TaskObject; +import GraphQL.Today.UnionTypeObject; + import GraphQL.Today.Mock; using namespace graphql; diff --git a/test/TodayTests.cpp b/test/TodayTests.cpp index 586cb6cb..ac5fb6d2 100644 --- a/test/TodayTests.cpp +++ b/test/TodayTests.cpp @@ -3,14 +3,37 @@ #include -#include "graphqlservice/JSONResponse.h" - #include #include +#include import GraphQL.Parse; +import GraphQL.Response; +import GraphQL.JSONResponse; import GraphQL.Service; +import GraphQL.Today.TodaySchema; + +import GraphQL.Today.QueryObject; +import GraphQL.Today.MutationObject; +import GraphQL.Today.SubscriptionObject; + +import GraphQL.Today.AppointmentEdgeObject; +import GraphQL.Today.AppointmentObject; +import GraphQL.Today.AppointmentConnectionObject; +import GraphQL.Today.CompleteTaskPayloadObject; +import GraphQL.Today.ExpensiveObject; +import GraphQL.Today.FolderEdgeObject; +import GraphQL.Today.FolderObject; +import GraphQL.Today.FolderConnectionObject; +import GraphQL.Today.NestedTypeObject; +import GraphQL.Today.NodeObject; +import GraphQL.Today.PageInfoObject; +import GraphQL.Today.TaskConnectionObject; +import GraphQL.Today.TaskEdgeObject; +import GraphQL.Today.TaskObject; +import GraphQL.Today.UnionTypeObject; + import GraphQL.Today.Mock; using namespace graphql; From 31150a29d0cd54f28681ce273f82478aa5ec8c78 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 16:20:13 -0700 Subject: [PATCH 048/123] fix(modules): re-export transitive module dependencies --- include/graphqlservice/Client.ixx | 2 + include/graphqlservice/JSONResponse.ixx | 2 + include/graphqlservice/Service.ixx | 3 ++ .../introspection/IntrospectionSchema.ixx | 7 ++- samples/client/benchmark.cpp | 23 --------- samples/learn/schema/StarWarsSchema.ixx | 7 ++- samples/today/TodayMock.ixx | 2 + samples/today/benchmark.cpp | 23 --------- samples/today/nointrospection/TodaySchema.ixx | 19 +++++++- samples/today/sample.cpp | 23 --------- samples/today/schema/TodaySchema.ixx | 19 +++++++- .../validation/schema/ValidationSchema.ixx | 18 ++++++- src/SchemaGenerator.cpp | 47 +++++++++++++++++-- src/introspection/IntrospectionSchema.ixx | 7 ++- test/ClientTests.cpp | 23 --------- test/CoroutineTests.cpp | 23 --------- test/NoIntrospectionTests.cpp | 23 --------- test/TodayTests.cpp | 23 --------- 18 files changed, 123 insertions(+), 171 deletions(-) diff --git a/include/graphqlservice/Client.ixx b/include/graphqlservice/Client.ixx index 7db2df94..9740d304 100644 --- a/include/graphqlservice/Client.ixx +++ b/include/graphqlservice/Client.ixx @@ -7,6 +7,8 @@ module; export module GraphQL.Client; +export import GraphQL.Response; + export namespace graphql::client { // clang-format off diff --git a/include/graphqlservice/JSONResponse.ixx b/include/graphqlservice/JSONResponse.ixx index 4fc5106d..ff36ba7e 100644 --- a/include/graphqlservice/JSONResponse.ixx +++ b/include/graphqlservice/JSONResponse.ixx @@ -7,6 +7,8 @@ module; export module GraphQL.JSONResponse; +export import GraphQL.Response; + export namespace graphql::response { // clang-format off diff --git a/include/graphqlservice/Service.ixx b/include/graphqlservice/Service.ixx index 62f1380d..83b88a2f 100644 --- a/include/graphqlservice/Service.ixx +++ b/include/graphqlservice/Service.ixx @@ -7,6 +7,9 @@ module; export module GraphQL.Service; +export import GraphQL.Parse; +export import GraphQL.Response; + export namespace graphql { namespace schema { diff --git a/include/graphqlservice/introspection/IntrospectionSchema.ixx b/include/graphqlservice/introspection/IntrospectionSchema.ixx index 2044667f..45f3f14a 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.ixx +++ b/include/graphqlservice/introspection/IntrospectionSchema.ixx @@ -9,7 +9,12 @@ module; export module GraphQL.Introspection.IntrospectionSchema; -namespace included = graphql::introspection; +export import GraphQL.Introspection.SchemaObject; +export import GraphQL.Introspection.TypeObject; +export import GraphQL.Introspection.FieldObject; +export import GraphQL.Introspection.InputValueObject; +export import GraphQL.Introspection.EnumValueObject; +export import GraphQL.Introspection.DirectiveObject; export namespace graphql::introspection { diff --git a/samples/client/benchmark.cpp b/samples/client/benchmark.cpp index ba959aa6..10c56b13 100644 --- a/samples/client/benchmark.cpp +++ b/samples/client/benchmark.cpp @@ -12,31 +12,8 @@ #include import GraphQL.Client; -import GraphQL.Response; import GraphQL.Service; -import GraphQL.Today.TodaySchema; - -import GraphQL.Today.QueryObject; -import GraphQL.Today.MutationObject; -import GraphQL.Today.SubscriptionObject; - -import GraphQL.Today.AppointmentEdgeObject; -import GraphQL.Today.AppointmentObject; -import GraphQL.Today.AppointmentConnectionObject; -import GraphQL.Today.CompleteTaskPayloadObject; -import GraphQL.Today.ExpensiveObject; -import GraphQL.Today.FolderEdgeObject; -import GraphQL.Today.FolderObject; -import GraphQL.Today.FolderConnectionObject; -import GraphQL.Today.NestedTypeObject; -import GraphQL.Today.NodeObject; -import GraphQL.Today.PageInfoObject; -import GraphQL.Today.TaskConnectionObject; -import GraphQL.Today.TaskEdgeObject; -import GraphQL.Today.TaskObject; -import GraphQL.Today.UnionTypeObject; - import GraphQL.Today.Mock; import GraphQL.Benchmark.BenchmarkClient; diff --git a/samples/learn/schema/StarWarsSchema.ixx b/samples/learn/schema/StarWarsSchema.ixx index 64ef57b0..45885809 100644 --- a/samples/learn/schema/StarWarsSchema.ixx +++ b/samples/learn/schema/StarWarsSchema.ixx @@ -9,7 +9,12 @@ module; export module GraphQL.StarWars.StarWarsSchema; -namespace included = graphql::learn; +export import GraphQL.StarWars.CharacterObject; +export import GraphQL.StarWars.HumanObject; +export import GraphQL.StarWars.DroidObject; +export import GraphQL.StarWars.QueryObject; +export import GraphQL.StarWars.ReviewObject; +export import GraphQL.StarWars.MutationObject; export namespace graphql::learn { diff --git a/samples/today/TodayMock.ixx b/samples/today/TodayMock.ixx index f8142989..3bd76425 100644 --- a/samples/today/TodayMock.ixx +++ b/samples/today/TodayMock.ixx @@ -7,6 +7,8 @@ module; export module GraphQL.Today.Mock; +export import GraphQL.Today.TodaySchema; + export namespace graphql::today { // clang-format off diff --git a/samples/today/benchmark.cpp b/samples/today/benchmark.cpp index b1c7f7dd..bec9c86d 100644 --- a/samples/today/benchmark.cpp +++ b/samples/today/benchmark.cpp @@ -11,32 +11,9 @@ #include import GraphQL.Parse; -import GraphQL.Response; import GraphQL.JSONResponse; import GraphQL.Service; -import GraphQL.Today.TodaySchema; - -import GraphQL.Today.QueryObject; -import GraphQL.Today.MutationObject; -import GraphQL.Today.SubscriptionObject; - -import GraphQL.Today.AppointmentEdgeObject; -import GraphQL.Today.AppointmentObject; -import GraphQL.Today.AppointmentConnectionObject; -import GraphQL.Today.CompleteTaskPayloadObject; -import GraphQL.Today.ExpensiveObject; -import GraphQL.Today.FolderEdgeObject; -import GraphQL.Today.FolderObject; -import GraphQL.Today.FolderConnectionObject; -import GraphQL.Today.NestedTypeObject; -import GraphQL.Today.NodeObject; -import GraphQL.Today.PageInfoObject; -import GraphQL.Today.TaskConnectionObject; -import GraphQL.Today.TaskEdgeObject; -import GraphQL.Today.TaskObject; -import GraphQL.Today.UnionTypeObject; - import GraphQL.Today.Mock; using namespace graphql; diff --git a/samples/today/nointrospection/TodaySchema.ixx b/samples/today/nointrospection/TodaySchema.ixx index 0230a5ab..7bfef47c 100644 --- a/samples/today/nointrospection/TodaySchema.ixx +++ b/samples/today/nointrospection/TodaySchema.ixx @@ -9,7 +9,24 @@ module; export module GraphQL.Today.TodaySchema; -namespace included = graphql::today; +export import GraphQL.Today.NodeObject; +export import GraphQL.Today.UnionTypeObject; +export import GraphQL.Today.QueryObject; +export import GraphQL.Today.PageInfoObject; +export import GraphQL.Today.AppointmentEdgeObject; +export import GraphQL.Today.AppointmentConnectionObject; +export import GraphQL.Today.TaskEdgeObject; +export import GraphQL.Today.TaskConnectionObject; +export import GraphQL.Today.FolderEdgeObject; +export import GraphQL.Today.FolderConnectionObject; +export import GraphQL.Today.CompleteTaskPayloadObject; +export import GraphQL.Today.MutationObject; +export import GraphQL.Today.SubscriptionObject; +export import GraphQL.Today.AppointmentObject; +export import GraphQL.Today.TaskObject; +export import GraphQL.Today.FolderObject; +export import GraphQL.Today.NestedTypeObject; +export import GraphQL.Today.ExpensiveObject; export namespace graphql::today { diff --git a/samples/today/sample.cpp b/samples/today/sample.cpp index 5f91c550..e4a313bd 100644 --- a/samples/today/sample.cpp +++ b/samples/today/sample.cpp @@ -7,32 +7,9 @@ #include import GraphQL.Parse; -import GraphQL.Response; import GraphQL.JSONResponse; import GraphQL.Service; -import GraphQL.Today.TodaySchema; - -import GraphQL.Today.QueryObject; -import GraphQL.Today.MutationObject; -import GraphQL.Today.SubscriptionObject; - -import GraphQL.Today.AppointmentEdgeObject; -import GraphQL.Today.AppointmentObject; -import GraphQL.Today.AppointmentConnectionObject; -import GraphQL.Today.CompleteTaskPayloadObject; -import GraphQL.Today.ExpensiveObject; -import GraphQL.Today.FolderEdgeObject; -import GraphQL.Today.FolderObject; -import GraphQL.Today.FolderConnectionObject; -import GraphQL.Today.NestedTypeObject; -import GraphQL.Today.NodeObject; -import GraphQL.Today.PageInfoObject; -import GraphQL.Today.TaskConnectionObject; -import GraphQL.Today.TaskEdgeObject; -import GraphQL.Today.TaskObject; -import GraphQL.Today.UnionTypeObject; - import GraphQL.Today.Mock; using namespace graphql; diff --git a/samples/today/schema/TodaySchema.ixx b/samples/today/schema/TodaySchema.ixx index 0230a5ab..7bfef47c 100644 --- a/samples/today/schema/TodaySchema.ixx +++ b/samples/today/schema/TodaySchema.ixx @@ -9,7 +9,24 @@ module; export module GraphQL.Today.TodaySchema; -namespace included = graphql::today; +export import GraphQL.Today.NodeObject; +export import GraphQL.Today.UnionTypeObject; +export import GraphQL.Today.QueryObject; +export import GraphQL.Today.PageInfoObject; +export import GraphQL.Today.AppointmentEdgeObject; +export import GraphQL.Today.AppointmentConnectionObject; +export import GraphQL.Today.TaskEdgeObject; +export import GraphQL.Today.TaskConnectionObject; +export import GraphQL.Today.FolderEdgeObject; +export import GraphQL.Today.FolderConnectionObject; +export import GraphQL.Today.CompleteTaskPayloadObject; +export import GraphQL.Today.MutationObject; +export import GraphQL.Today.SubscriptionObject; +export import GraphQL.Today.AppointmentObject; +export import GraphQL.Today.TaskObject; +export import GraphQL.Today.FolderObject; +export import GraphQL.Today.NestedTypeObject; +export import GraphQL.Today.ExpensiveObject; export namespace graphql::today { diff --git a/samples/validation/schema/ValidationSchema.ixx b/samples/validation/schema/ValidationSchema.ixx index a4083ca0..0501c3ec 100644 --- a/samples/validation/schema/ValidationSchema.ixx +++ b/samples/validation/schema/ValidationSchema.ixx @@ -9,7 +9,23 @@ module; export module GraphQL.Validation.ValidationSchema; -namespace included = graphql::validation; +export import GraphQL.Validation.SentientObject; +export import GraphQL.Validation.PetObject; +export import GraphQL.Validation.NodeObject; +export import GraphQL.Validation.ResourceObject; +export import GraphQL.Validation.CatOrDogObject; +export import GraphQL.Validation.DogOrHumanObject; +export import GraphQL.Validation.HumanOrAlienObject; +export import GraphQL.Validation.QueryObject; +export import GraphQL.Validation.DogObject; +export import GraphQL.Validation.AlienObject; +export import GraphQL.Validation.HumanObject; +export import GraphQL.Validation.CatObject; +export import GraphQL.Validation.MutationObject; +export import GraphQL.Validation.MutateDogResultObject; +export import GraphQL.Validation.SubscriptionObject; +export import GraphQL.Validation.MessageObject; +export import GraphQL.Validation.ArgumentsObject; export namespace graphql::validation { diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index d2af0e43..c6ef33df 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -709,14 +709,52 @@ module; export module GraphQL.)cpp" << _loader.getFilenamePrefix() << R"cpp(.)cpp" << _loader.getFilenamePrefix() << R"cpp(Schema; +)cpp"; + + PendingBlankLine pendingSeparator { moduleFile }; + + if (!_loader.getInterfaceTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& interfaceType : _loader.getInterfaceTypes()) + { + moduleFile << R"cpp(export import GraphQL.)cpp" << _loader.getFilenamePrefix() + << R"cpp(.)cpp" << interfaceType.cppType << R"cpp(Object; +)cpp"; + } + } + + if (!_loader.getUnionTypes().empty()) + { + pendingSeparator.reset(); -namespace included = )cpp" - << schemaNamespace << R"cpp(; + for (const auto& unionType : _loader.getUnionTypes()) + { + moduleFile << R"cpp(export import GraphQL.)cpp" << _loader.getFilenamePrefix() + << R"cpp(.)cpp" << unionType.cppType << R"cpp(Object; +)cpp"; + } + } + + if (!_loader.getObjectTypes().empty()) + { + pendingSeparator.reset(); + for (const auto& objectType : _loader.getObjectTypes()) + { + moduleFile << R"cpp(export import GraphQL.)cpp" << _loader.getFilenamePrefix() + << R"cpp(.)cpp" << objectType.cppType << R"cpp(Object; +)cpp"; + } + } + + moduleFile << R"cpp( export )cpp"; NamespaceScope graphqlNamespace { moduleFile, schemaNamespace }; - PendingBlankLine pendingSeparator { moduleFile }; + + pendingSeparator.add(); if (!_loader.getEnumTypes().empty()) { @@ -2262,7 +2300,8 @@ Operations::Operations()cpp"; )cpp"; } sourceFile << R"cpp(}, )cpp" - << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") << R"cpp()); + << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") + << R"cpp()); )cpp"; } } diff --git a/src/introspection/IntrospectionSchema.ixx b/src/introspection/IntrospectionSchema.ixx index 2044667f..45f3f14a 100644 --- a/src/introspection/IntrospectionSchema.ixx +++ b/src/introspection/IntrospectionSchema.ixx @@ -9,7 +9,12 @@ module; export module GraphQL.Introspection.IntrospectionSchema; -namespace included = graphql::introspection; +export import GraphQL.Introspection.SchemaObject; +export import GraphQL.Introspection.TypeObject; +export import GraphQL.Introspection.FieldObject; +export import GraphQL.Introspection.InputValueObject; +export import GraphQL.Introspection.EnumValueObject; +export import GraphQL.Introspection.DirectiveObject; export namespace graphql::introspection { diff --git a/test/ClientTests.cpp b/test/ClientTests.cpp index 647ac109..5a576b66 100644 --- a/test/ClientTests.cpp +++ b/test/ClientTests.cpp @@ -8,7 +8,6 @@ #include import GraphQL.Parse; -import GraphQL.Response; import GraphQL.Client; import GraphQL.Service; @@ -16,28 +15,6 @@ import GraphQL.Mutate.MutateClient; import GraphQL.Query.QueryClient; import GraphQL.Subscribe.SubscribeClient; -import GraphQL.Today.TodaySchema; - -import GraphQL.Today.QueryObject; -import GraphQL.Today.MutationObject; -import GraphQL.Today.SubscriptionObject; - -import GraphQL.Today.AppointmentEdgeObject; -import GraphQL.Today.AppointmentObject; -import GraphQL.Today.AppointmentConnectionObject; -import GraphQL.Today.CompleteTaskPayloadObject; -import GraphQL.Today.ExpensiveObject; -import GraphQL.Today.FolderEdgeObject; -import GraphQL.Today.FolderObject; -import GraphQL.Today.FolderConnectionObject; -import GraphQL.Today.NestedTypeObject; -import GraphQL.Today.NodeObject; -import GraphQL.Today.PageInfoObject; -import GraphQL.Today.TaskConnectionObject; -import GraphQL.Today.TaskEdgeObject; -import GraphQL.Today.TaskObject; -import GraphQL.Today.UnionTypeObject; - import GraphQL.Today.Mock; using namespace graphql; diff --git a/test/CoroutineTests.cpp b/test/CoroutineTests.cpp index 4cea58ea..435e0df8 100644 --- a/test/CoroutineTests.cpp +++ b/test/CoroutineTests.cpp @@ -7,32 +7,9 @@ #include import GraphQL.Parse; -import GraphQL.Response; import GraphQL.JSONResponse; import GraphQL.Service; -import GraphQL.Today.TodaySchema; - -import GraphQL.Today.QueryObject; -import GraphQL.Today.MutationObject; -import GraphQL.Today.SubscriptionObject; - -import GraphQL.Today.AppointmentEdgeObject; -import GraphQL.Today.AppointmentObject; -import GraphQL.Today.AppointmentConnectionObject; -import GraphQL.Today.CompleteTaskPayloadObject; -import GraphQL.Today.ExpensiveObject; -import GraphQL.Today.FolderEdgeObject; -import GraphQL.Today.FolderObject; -import GraphQL.Today.FolderConnectionObject; -import GraphQL.Today.NestedTypeObject; -import GraphQL.Today.NodeObject; -import GraphQL.Today.PageInfoObject; -import GraphQL.Today.TaskConnectionObject; -import GraphQL.Today.TaskEdgeObject; -import GraphQL.Today.TaskObject; -import GraphQL.Today.UnionTypeObject; - import GraphQL.Today.Mock; using namespace graphql; diff --git a/test/NoIntrospectionTests.cpp b/test/NoIntrospectionTests.cpp index b19cd1c6..c8779b42 100644 --- a/test/NoIntrospectionTests.cpp +++ b/test/NoIntrospectionTests.cpp @@ -8,32 +8,9 @@ #include import GraphQL.Parse; -import GraphQL.Response; import GraphQL.JSONResponse; import GraphQL.Service; -import GraphQL.Today.TodaySchema; - -import GraphQL.Today.QueryObject; -import GraphQL.Today.MutationObject; -import GraphQL.Today.SubscriptionObject; - -import GraphQL.Today.AppointmentEdgeObject; -import GraphQL.Today.AppointmentObject; -import GraphQL.Today.AppointmentConnectionObject; -import GraphQL.Today.CompleteTaskPayloadObject; -import GraphQL.Today.ExpensiveObject; -import GraphQL.Today.FolderEdgeObject; -import GraphQL.Today.FolderObject; -import GraphQL.Today.FolderConnectionObject; -import GraphQL.Today.NestedTypeObject; -import GraphQL.Today.NodeObject; -import GraphQL.Today.PageInfoObject; -import GraphQL.Today.TaskConnectionObject; -import GraphQL.Today.TaskEdgeObject; -import GraphQL.Today.TaskObject; -import GraphQL.Today.UnionTypeObject; - import GraphQL.Today.Mock; using namespace graphql; diff --git a/test/TodayTests.cpp b/test/TodayTests.cpp index ac5fb6d2..48699123 100644 --- a/test/TodayTests.cpp +++ b/test/TodayTests.cpp @@ -8,32 +8,9 @@ #include import GraphQL.Parse; -import GraphQL.Response; import GraphQL.JSONResponse; import GraphQL.Service; -import GraphQL.Today.TodaySchema; - -import GraphQL.Today.QueryObject; -import GraphQL.Today.MutationObject; -import GraphQL.Today.SubscriptionObject; - -import GraphQL.Today.AppointmentEdgeObject; -import GraphQL.Today.AppointmentObject; -import GraphQL.Today.AppointmentConnectionObject; -import GraphQL.Today.CompleteTaskPayloadObject; -import GraphQL.Today.ExpensiveObject; -import GraphQL.Today.FolderEdgeObject; -import GraphQL.Today.FolderObject; -import GraphQL.Today.FolderConnectionObject; -import GraphQL.Today.NestedTypeObject; -import GraphQL.Today.NodeObject; -import GraphQL.Today.PageInfoObject; -import GraphQL.Today.TaskConnectionObject; -import GraphQL.Today.TaskEdgeObject; -import GraphQL.Today.TaskObject; -import GraphQL.Today.UnionTypeObject; - import GraphQL.Today.Mock; using namespace graphql; From 63af1a8a387f9378b4fe89db73bf053bc12c3482 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 19:22:52 -0700 Subject: [PATCH 049/123] fix(cmake): remove old try_compile tests --- cmake/test_boost_beast.cpp | 15 -------- cmake/test_coroutine.cpp | 59 ------------------------------ cmake/test_filesystem.cpp | 19 ---------- src/CMakeLists.txt | 73 +------------------------------------- 4 files changed, 1 insertion(+), 165 deletions(-) delete mode 100644 cmake/test_boost_beast.cpp delete mode 100644 cmake/test_coroutine.cpp delete mode 100644 cmake/test_filesystem.cpp diff --git a/cmake/test_boost_beast.cpp b/cmake/test_boost_beast.cpp deleted file mode 100644 index b59b338a..00000000 --- a/cmake/test_boost_beast.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// This is a dummy program that just needs to compile to tell us if Boost.Asio -// supports co_await and Boost.Beast is installed. - -#include - -#include - -int main() -{ -#ifdef BOOST_ASIO_HAS_CO_AWAIT - return 0; -#else - #error BOOST_ASIO_HAS_CO_AWAIT is undefined -#endif -} \ No newline at end of file diff --git a/cmake/test_coroutine.cpp b/cmake/test_coroutine.cpp deleted file mode 100644 index f3c5f52f..00000000 --- a/cmake/test_coroutine.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// This is a dummy program that just needs to compile and link to tell us if -// the C++20 coroutine API is available. Use CMake's configure_file command -// to replace the COROUTINE_HEADER and COROUTINE_NAMESPACE tokens for each -// combination of headers and namespaces which we want to pass to the CMake -// try_compile command. - -#include -#include - -struct task -{ - struct promise_type - { - task get_return_object() noexcept - { - return {}; - } - - std::suspend_never initial_suspend() noexcept - { - return {}; - } - - std::suspend_never final_suspend() noexcept - { - return {}; - } - - void return_void() noexcept - { - promise.set_value(); - } - - void unhandled_exception() - { - promise.set_exception(std::current_exception()); - } - - std::promise promise; - }; - - constexpr bool await_ready() const noexcept - { - return true; - } - - std::future future; -}; - -task test_co_return() -{ - co_return; -} - -int main() -{ - test_co_return().future.get(); - return 0; -} \ No newline at end of file diff --git a/cmake/test_filesystem.cpp b/cmake/test_filesystem.cpp deleted file mode 100644 index 240e7d6b..00000000 --- a/cmake/test_filesystem.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// This is a dummy program that just needs to compile and link to tell us if -// the C++17 std::filesystem API requires any additional libraries. - -#include - -int main() -{ - try - { - throw std::filesystem::filesystem_error("instantiate one to make sure it links", - std::make_error_code(std::errc::function_not_supported)); - } - catch (const std::filesystem::filesystem_error& error) - { - return -1; - } - - return !std::filesystem::temp_directory_path().is_absolute(); -} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8b6b484f..a7adfd46 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -129,42 +129,6 @@ target_sources(graphql_introspection_modules FILES ${INTROSPECTION_MODULES}) -function(check_coroutine_impl OPTIONAL_FLAGS OUT_RESULT) - set(TEST_FILE "test_coroutine.cpp") - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/${TEST_FILE} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - - try_compile(TEST_RESULT - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/${TEST_FILE} - CXX_STANDARD 20) - - if(NOT TEST_RESULT) - # Retry with each of the optional flags. - foreach(OPTIONAL_FLAG IN LISTS OPTIONAL_FLAGS) - try_compile(TEST_RESULT - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/${TEST_FILE} - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPTIONAL_FLAG}" - CXX_STANDARD 20) - - if(TEST_RESULT) - # Looks like the optional flag was required, go ahead and add it to the compile options. - target_compile_options(graphql_internal_modules INTERFACE ${OPTIONAL_FLAG}) - break() - endif() - endforeach(OPTIONAL_FLAG) - endif() - - set(${OUT_RESULT} ${TEST_RESULT} PARENT_SCOPE) -endfunction() - -check_coroutine_impl("-fcoroutines" STD_COROUTINE) -if(STD_COROUTINE) - message(STATUS "Using std coroutine") -else() - message(FATAL_ERROR "Missing coroutine support") -endif() - # graphqlpeg add_library(graphqlpeg SyntaxTree.cpp) add_library(cppgraphqlgen::graphqlpeg ALIAS graphqlpeg) @@ -342,43 +306,8 @@ if(GRAPHQL_BUILD_SCHEMAGEN) RUNTIME DESTINATION ${GRAPHQL_INSTALL_TOOLS_DIR}/${PROJECT_NAME}) endif() -# Common schemagen and clientgen filesystem and Boost dependencies +# Common schemagen and clientgen Boost dependencies if(GRAPHQL_BUILD_SCHEMAGEN OR GRAPHQL_BUILD_CLIENTGEN) - # Try compiling a test program with std::filesystem or one of its alternatives. - function(check_filesystem_impl OPTIONAL_LIBS) - try_compile(TEST_RESULT - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/test_filesystem.cpp - CXX_STANDARD 20) - - if(NOT TEST_RESULT) - # Retry with each of the optional libraries. - foreach(OPTIONAL_LIB IN LISTS OPTIONAL_LIBS) - try_compile(TEST_RESULT - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/${TEST_FILE} - LINK_LIBRARIES ${OPTIONAL_LIB} - CXX_STANDARD 20) - - if(TEST_RESULT) - # Looks like the optional library was required, go ahead and add it to the link options. - if(GRAPHQL_BUILD_SCHEMAGEN) - target_link_libraries(schemagen PRIVATE ${OPTIONAL_LIB}) - endif() - if(GRAPHQL_BUILD_CLIENTGEN) - target_link_libraries(clientgen PRIVATE ${OPTIONAL_LIB}) - endif() - break() - endif() - endforeach(OPTIONAL_LIB) - endif() - endfunction(check_filesystem_impl) - - # Try compiling a minimal program without any extra libraries, then with each optional library until it succeeded: - # stdc++fs - # c++fs - check_filesystem_impl("stdc++fs;c++fs" STD_FILESYTEM) - find_package(boost_program_options CONFIG REQUIRED) if(GRAPHQL_BUILD_SCHEMAGEN) target_link_libraries(schemagen PRIVATE Boost::program_options) From 598d6272703dd602a7acde29d72e1e0af8725a12 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 19:24:43 -0700 Subject: [PATCH 050/123] feat(cmake): add a project CMakePresets.json file --- CMakePresets.json | 89 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 CMakePresets.json diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 00000000..70f25483 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,89 @@ +{ + "version": 8, + "configurePresets": [ + { + "hidden": true, + "name": "ninja-generator", + "binaryDir": "build/${presetName}", + "toolchainFile": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake", + "generator": "Ninja" + }, + { + "name": "debug", + "inherits": [ "ninja-generator" ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "release", + "inherits": [ "ninja-generator" ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "gcc-14", + "inherits": [ "debug" ], + "condition": { + "type": "notEquals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "cacheVariables": { + "CMAKE_C_COMPILER": "/usr/bin/gcc-14", + "CMAKE_CXX_COMPILER": "/usr/bin/g++-14" + } + }, + { + "name": "clang-18", + "inherits": [ "debug" ], + "condition": { + "type": "notEquals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "cacheVariables": { + "CMAKE_C_COMPILER": "/usr/bin/clang-18", + "CMAKE_CXX_COMPILER": "/usr/bin/clang++-18", + "CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS": "/usr/bin/clang-scan-deps-18" + } + } + ], + "buildPresets": [ + { + "name": "debug", + "configurePreset": "debug" + }, + { + "name": "release", + "configurePreset": "release" + }, + { + "name": "gcc-14", + "configurePreset": "gcc-14" + }, + { + "name": "clang-18", + "configurePreset": "clang-18" + } + ], + "testPresets": [ + { + "name": "debug", + "configurePreset": "debug" + }, + { + "name": "release", + "configurePreset": "release" + }, + { + "name": "gcc-14", + "configurePreset": "gcc-14" + }, + { + "name": "clang-18", + "configurePreset": "clang-18" + } + ] +} \ No newline at end of file From 3f53e2bd6e2630d09cf87398742100fbe6874089 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 19:55:24 -0700 Subject: [PATCH 051/123] fix(workflow): switch the Linux CI to clang-18 presets --- .github/workflows/linux.yml | 22 +++++----------- CMakePresets.json | 52 +++++++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 58921f51..135b36d9 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -3,11 +3,11 @@ name: Linux on: [push, pull_request] jobs: - gcc14: + clang-18: strategy: fail-fast: false matrix: - config: [Debug, Release] + config: [debug, release] runs-on: ubuntu-24.04 @@ -18,17 +18,15 @@ jobs: - name: Install Dependencies run: | - sudo apt-get update - sudo apt-get upgrade sudo add-apt-repository -y universe sudo apt-get update - sudo apt-get install -yq libgtest-dev libboost-program-options-dev rapidjson-dev ninja-build gcc-14 g++-14 + sudo apt-get install -yq libgtest-dev libboost-program-options-dev rapidjson-dev ninja-build - name: Build GTest run: | cmake -E make_directory gtest cd gtest - cmake -DCMAKE_BUILD_TYPE=${{ matrix.config }} -G Ninja /usr/src/gtest + cmake -DCMAKE_BUILD_TYPE=${{ matrix.config == 'debug' && 'Debug' || 'Release' }} -G Ninja /usr/src/gtest cmake --build . -j -v sudo cmake --install . @@ -37,19 +35,13 @@ jobs: - name: Configure CMake shell: pwsh - env: - CC: gcc-14 - CXX: g++-14 - working-directory: build/ run: | - $cmakeBuildType = '${{ matrix.config }}' - - cmake "-DCMAKE_BUILD_TYPE=$cmakeBuildType" -G Ninja ${{ github.workspace }} + cmake --preset clang-18-${{ matrix.config }} - name: Build working-directory: build/ - run: cmake --build . -j -v + run: cmake --build --preset clang-18-${{ matrix.config }} -j -v - name: Test working-directory: build/ - run: ctest --output-on-failure + run: ctest --preset clang-18-${{ matrix.config }} --output-on-failure diff --git a/CMakePresets.json b/CMakePresets.json index 70f25483..4b6a6d0c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -19,11 +19,11 @@ "name": "release", "inherits": [ "ninja-generator" ], "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithDebInfo" + "CMAKE_BUILD_TYPE": "Release" } }, { - "name": "gcc-14", + "name": "gcc-14-debug", "inherits": [ "debug" ], "condition": { "type": "notEquals", @@ -36,7 +36,14 @@ } }, { - "name": "clang-18", + "name": "gcc-14-release", + "inherits": [ "gcc-14-debug" ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "clang-18-debug", "inherits": [ "debug" ], "condition": { "type": "notEquals", @@ -48,6 +55,13 @@ "CMAKE_CXX_COMPILER": "/usr/bin/clang++-18", "CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS": "/usr/bin/clang-scan-deps-18" } + }, + { + "name": "clang-18-release", + "inherits": [ "clang-18-debug" ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } } ], "buildPresets": [ @@ -60,12 +74,20 @@ "configurePreset": "release" }, { - "name": "gcc-14", - "configurePreset": "gcc-14" + "name": "gcc-14-debug", + "configurePreset": "gcc-14-debug" + }, + { + "name": "gcc-14-release", + "configurePreset": "gcc-14-release" + }, + { + "name": "clang-18-debug", + "configurePreset": "clang-18-debug" }, { - "name": "clang-18", - "configurePreset": "clang-18" + "name": "clang-18-release", + "configurePreset": "clang-18-release" } ], "testPresets": [ @@ -78,12 +100,20 @@ "configurePreset": "release" }, { - "name": "gcc-14", - "configurePreset": "gcc-14" + "name": "gcc-14-debug", + "configurePreset": "gcc-14-debug" + }, + { + "name": "gcc-14-release", + "configurePreset": "gcc-14-release" + }, + { + "name": "clang-18-debug", + "configurePreset": "clang-18-debug" }, { - "name": "clang-18", - "configurePreset": "clang-18" + "name": "clang-18-release", + "configurePreset": "clang-18-release" } ] } \ No newline at end of file From a9540525dc033f2ecf36ea68cf0f79a1c032200c Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 20:21:51 -0700 Subject: [PATCH 052/123] fix(ci): suppress vcpkg toolchain file on Linux CI --- .github/workflows/linux.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 135b36d9..af835ca4 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -34,9 +34,7 @@ jobs: run: cmake -E make_directory build - name: Configure CMake - shell: pwsh - run: | - cmake --preset clang-18-${{ matrix.config }} + run: cmake --preset clang-18-${{ matrix.config }} -DCMAKE_TOOLCHAIN_FILE= - name: Build working-directory: build/ From b52d9a302d6e56507097db3138ac7b17e44e2984 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 20:25:16 -0700 Subject: [PATCH 053/123] fix(ci): use preset from source directory --- .github/workflows/linux.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index af835ca4..c09b0879 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -37,9 +37,7 @@ jobs: run: cmake --preset clang-18-${{ matrix.config }} -DCMAKE_TOOLCHAIN_FILE= - name: Build - working-directory: build/ run: cmake --build --preset clang-18-${{ matrix.config }} -j -v - name: Test - working-directory: build/ run: ctest --preset clang-18-${{ matrix.config }} --output-on-failure From 4c94d19697e49e748d46710ef7ded57c75dd3f68 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 21:43:52 -0700 Subject: [PATCH 054/123] fix(ci): reenable gcc-14 by turning off modules --- .github/workflows/linux.yml | 9 +- CMakeLists.txt | 6 +- CMakePresets.json | 3 +- cmake/cppgraphqlgen-functions.cmake | 46 ++++----- samples/CMakeLists.txt | 5 +- samples/client/CMakeLists.txt | 48 ++++----- samples/today/CMakeLists.txt | 22 ++-- src/CMakeLists.txt | 149 +++++++++++++--------------- test/CMakeLists.txt | 94 +++++++++--------- 9 files changed, 185 insertions(+), 197 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c09b0879..048858ca 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -3,10 +3,11 @@ name: Linux on: [push, pull_request] jobs: - clang-18: + Linux: strategy: fail-fast: false matrix: + compiler: [gcc-14, clang-18] config: [debug, release] runs-on: ubuntu-24.04 @@ -34,10 +35,10 @@ jobs: run: cmake -E make_directory build - name: Configure CMake - run: cmake --preset clang-18-${{ matrix.config }} -DCMAKE_TOOLCHAIN_FILE= + run: cmake --preset ${{ matrix.compiler }}-${{ matrix.config }} -DCMAKE_TOOLCHAIN_FILE= - name: Build - run: cmake --build --preset clang-18-${{ matrix.config }} -j -v + run: cmake --build --preset ${{ matrix.compiler }}-${{ matrix.config }} -j -v - name: Test - run: ctest --preset clang-18-${{ matrix.config }} --output-on-failure + run: ctest --preset ${{ matrix.compiler }}-${{ matrix.config }} --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt index f3cb9a2f..753aca8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") endif() endif() +option(GRAPHQL_BUILD_MODULES "Build the C++20 module interface libraries." ON) option(GRAPHQL_BUILD_SCHEMAGEN "Build the schemagen tool." ON) option(GRAPHQL_BUILD_CLIENTGEN "Build the clientgen tool." ON) option(GRAPHQL_BUILD_TESTS "Build the tests and sample schema library." ON) @@ -102,11 +103,6 @@ else() add_compile_options(-Wall -Wextra -pedantic -Werror) endif() -# Workaround name mangling compatibility in GCC. -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - add_compile_options(-fabi-compat-version=19) -endif() - function(add_bigobj_flag target) if(MSVC) # MSVC requires the /bigobj flag if the number of sections gets too big. diff --git a/CMakePresets.json b/CMakePresets.json index 4b6a6d0c..942ec260 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -32,7 +32,8 @@ }, "cacheVariables": { "CMAKE_C_COMPILER": "/usr/bin/gcc-14", - "CMAKE_CXX_COMPILER": "/usr/bin/g++-14" + "CMAKE_CXX_COMPILER": "/usr/bin/g++-14", + "GRAPHQL_BUILD_MODULES": false } }, { diff --git a/cmake/cppgraphqlgen-functions.cmake b/cmake/cppgraphqlgen-functions.cmake index 15e3e7e9..5114c6b7 100644 --- a/cmake/cppgraphqlgen-functions.cmake +++ b/cmake/cppgraphqlgen-functions.cmake @@ -44,24 +44,21 @@ function(add_graphql_schema_target SCHEMA_TARGET) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_TARGET}_schema_files) file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_TARGET}_schema_files SCHEMA_FILES) - file(GLOB SCHEMA_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) - file(GLOB SCHEMA_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) add_library(${SCHEMA_TARGET}_schema STATIC ${SCHEMA_FILES}) add_dependencies(${SCHEMA_TARGET}_schema ${SCHEMA_TARGET}_update_schema) target_compile_features(${SCHEMA_TARGET}_schema PUBLIC cxx_std_20) target_include_directories(${SCHEMA_TARGET}_schema PUBLIC $) target_link_libraries(${SCHEMA_TARGET}_schema PUBLIC cppgraphqlgen::graphqlservice) - target_sources(${SCHEMA_TARGET}_schema - PUBLIC FILE_SET HEADERS - BASE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR} - FILES - ${SCHEMA_HEADERS} - PUBLIC FILE_SET CXX_MODULES - BASE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR} - FILES - ${SCHEMA_MODULES}) + file(GLOB SCHEMA_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) + target_sources(${SCHEMA_TARGET}_schema PUBLIC FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${SCHEMA_HEADERS}) + if(GRAPHQL_BUILD_MODULES) + file(GLOB SCHEMA_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) + target_sources(${SCHEMA_TARGET}_schema PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${SCHEMA_MODULES}) + endif() endif() endfunction() @@ -100,23 +97,20 @@ function(add_graphql_client_target CLIENT_TARGET) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${CLIENT_TARGET}_client_files) file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${CLIENT_TARGET}_client_files CLIENT_FILES) - file(GLOB CLIENT_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) - file(GLOB CLIENT_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) add_library(${CLIENT_TARGET}_client STATIC ${CLIENT_FILES}) add_dependencies(${CLIENT_TARGET}_client ${CLIENT_TARGET}_update_client) target_compile_features(${CLIENT_TARGET}_client PUBLIC cxx_std_20) target_include_directories(${CLIENT_TARGET}_client PUBLIC $) target_link_libraries(${CLIENT_TARGET}_client PUBLIC cppgraphqlgen::graphqlclient) - target_sources(${CLIENT_TARGET}_client - PUBLIC FILE_SET HEADERS - BASE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR} - FILES - ${CLIENT_HEADERS} - PUBLIC FILE_SET CXX_MODULES - BASE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR} - FILES - ${CLIENT_MODULES}) + file(GLOB CLIENT_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) + target_sources(${CLIENT_TARGET}_client PUBLIC FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CLIENT_HEADERS}) + if(GRAPHQL_BUILD_MODULES) + file(GLOB CLIENT_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) + target_sources(${CLIENT_TARGET}_client PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CLIENT_MODULES}) + endif() endif() endfunction() diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 0fcbfacf..eff2f4ca 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -5,9 +5,12 @@ cmake_minimum_required(VERSION 3.28) add_subdirectory(client) add_subdirectory(learn) -add_subdirectory(today) add_subdirectory(validation) +if(GRAPHQL_BUILD_MODULES) + add_subdirectory(today) +endif() + if(GRAPHQL_BUILD_HTTP_SAMPLE) find_package(boost_beast CONFIG QUIET) if(Boost_FOUND) diff --git a/samples/client/CMakeLists.txt b/samples/client/CMakeLists.txt index b5eb0d8a..a001c133 100644 --- a/samples/client/CMakeLists.txt +++ b/samples/client/CMakeLists.txt @@ -11,30 +11,32 @@ add_subdirectory(multiple) add_subdirectory(benchmark) -# client_benchmark -add_executable(client_benchmark benchmark.cpp) -target_link_libraries(client_benchmark PRIVATE - todaygraphql - benchmark_client) +if(GRAPHQL_BUILD_MODULES) + # client_benchmark + add_executable(client_benchmark benchmark.cpp) + target_link_libraries(client_benchmark PRIVATE + todaygraphql + benchmark_client) -if(WIN32 AND BUILD_SHARED_LIBS) - add_custom_command(OUTPUT copied_sample_dlls - COMMAND ${CMAKE_COMMAND} -E copy_if_different - $ - $ - $ - $ - $ - ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/copied_sample_dlls - DEPENDS - graphqlservice - graphqljson - graphqlpeg - graphqlresponse - graphqlclient) + if(WIN32 AND BUILD_SHARED_LIBS) + add_custom_command(OUTPUT copied_sample_dlls + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + $ + $ + $ + $ + ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/copied_sample_dlls + DEPENDS + graphqlservice + graphqljson + graphqlpeg + graphqlresponse + graphqlclient) - add_custom_target(copy_client_sample_dlls DEPENDS copied_sample_dlls) + add_custom_target(copy_client_sample_dlls DEPENDS copied_sample_dlls) - add_dependencies(client_benchmark copy_client_sample_dlls) + add_dependencies(client_benchmark copy_client_sample_dlls) + endif() endif() diff --git a/samples/today/CMakeLists.txt b/samples/today/CMakeLists.txt index e8b1e5b0..9b6e1a6e 100644 --- a/samples/today/CMakeLists.txt +++ b/samples/today/CMakeLists.txt @@ -8,26 +8,28 @@ add_subdirectory(schema) add_library(todaygraphql STATIC TodayMock.cpp) target_compile_features(todaygraphql PUBLIC cxx_std_20) target_link_libraries(todaygraphql PUBLIC today_schema) -target_sources(todaygraphql - PUBLIC FILE_SET HEADERS - BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} - FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.h - PUBLIC FILE_SET CXX_MODULES +target_sources(todaygraphql PUBLIC FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(todaygraphql PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.ixx) +endif() # todaygraphql_nointrospection add_subdirectory(nointrospection) add_library(todaygraphql_nointrospection STATIC TodayMock.cpp) target_compile_features(todaygraphql_nointrospection PUBLIC cxx_std_20) target_link_libraries(todaygraphql_nointrospection PUBLIC today_nointrospection_schema) -target_sources(todaygraphql_nointrospection - PUBLIC FILE_SET HEADERS - BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} - FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.h - PUBLIC FILE_SET CXX_MODULES +target_sources(todaygraphql_nointrospection PUBLIC FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(todaygraphql_nointrospection PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.ixx) +endif() if(MSVC) # warning C4702: unreachable code diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a7adfd46..c38242e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -76,13 +76,13 @@ file(REAL_PATH ../include/ INCLUDE_ROOT) # graphql_internal_modules add_library(graphql_internal_modules STATIC) add_library(cppgraphqlgen::graphql_internal_modules ALIAS graphql_internal_modules) +set_target_properties(graphql_internal_modules PROPERTIES LINKER_LANGUAGE CXX) target_compile_features(graphql_internal_modules PUBLIC cxx_std_20) target_link_libraries(graphql_internal_modules PUBLIC taocpp::pegtl) target_include_directories(graphql_internal_modules PUBLIC $ $) -target_sources(graphql_internal_modules - PUBLIC FILE_SET HEADERS +target_sources(graphql_internal_modules PUBLIC FILE_SET HEADERS BASE_DIRS ${INCLUDE_ROOT} FILES @@ -93,58 +93,55 @@ target_sources(graphql_internal_modules ${INCLUDE_ROOT}/graphqlservice/internal/Schema.h ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.h ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.h - ${INCLUDE_ROOT}/graphqlservice/internal/Version.h - PUBLIC FILE_SET CXX_MODULES - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Base64.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Schema.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.ixx - ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx) + ${INCLUDE_ROOT}/graphqlservice/internal/Version.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(graphql_internal_modules PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Base64.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Schema.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx) +endif() # graphql_introspection_modules add_library(graphql_introspection_modules STATIC) add_library(cppgraphqlgen::graphql_introspection_modules ALIAS graphql_introspection_modules) +set_target_properties(graphql_introspection_modules PROPERTIES LINKER_LANGUAGE CXX) target_compile_features(graphql_introspection_modules PUBLIC cxx_std_20) target_link_libraries(graphql_introspection_modules PUBLIC taocpp::pegtl) target_include_directories(graphql_introspection_modules PUBLIC $ $) file(GLOB INTROSPECTION_HEADERS ${INCLUDE_ROOT}/graphqlservice/introspection/*.h) -file(GLOB INTROSPECTION_MODULES ${INCLUDE_ROOT}/graphqlservice/introspection/*.ixx) -target_sources(graphql_introspection_modules - PUBLIC FILE_SET HEADERS - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INTROSPECTION_HEADERS} - PUBLIC FILE_SET CXX_MODULES - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INTROSPECTION_MODULES}) +target_sources(graphql_introspection_modules PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INTROSPECTION_HEADERS}) +if(GRAPHQL_BUILD_MODULES) + file(GLOB INTROSPECTION_MODULES ${INCLUDE_ROOT}/graphqlservice/introspection/*.ixx) + target_sources(graphql_introspection_modules PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INTROSPECTION_MODULES}) +endif() # graphqlpeg add_library(graphqlpeg SyntaxTree.cpp) add_library(cppgraphqlgen::graphqlpeg ALIAS graphqlpeg) target_compile_features(graphqlpeg PUBLIC cxx_std_20) target_link_libraries(graphqlpeg PUBLIC taocpp::pegtl) -target_sources(graphqlpeg - PUBLIC FILE_SET HEADERS - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/GraphQLParse.h - PUBLIC FILE_SET CXX_MODULES - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/Parse.ixx) +target_sources(graphqlpeg PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/GraphQLParse.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(graphqlpeg PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/Parse.ixx) +endif() target_include_directories(graphqlpeg PUBLIC $ $) @@ -172,17 +169,14 @@ target_include_directories(graphqlresponse PUBLIC $ $) target_link_libraries(graphqlresponse PUBLIC graphql_internal_modules) -target_sources(graphqlresponse - PUBLIC FILE_SET HEADERS - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/GraphQLResponse.h - PUBLIC FILE_SET CXX_MODULES - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/Response.ixx) +target_sources(graphqlresponse PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/GraphQLResponse.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(graphqlresponse PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/Response.ixx) +endif() if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqlresponse) @@ -336,17 +330,14 @@ target_link_libraries(graphqlservice PUBLIC graphqlpeg graphqlresponse Threads::Threads) -target_sources(graphqlservice - PUBLIC FILE_SET HEADERS - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/GraphQLService.h - PUBLIC FILE_SET CXX_MODULES - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/Service.ixx) +target_sources(graphqlservice PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/GraphQLService.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(graphqlservice PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/Service.ixx) +endif() if(GRAPHQL_UPDATE_SAMPLES) add_dependencies(graphqlservice copy_introspection_schema_headers) @@ -375,17 +366,14 @@ target_compile_features(graphqlclient PUBLIC cxx_std_20) target_link_libraries(graphqlclient PUBLIC graphqlpeg graphqlresponse) -target_sources(graphqlclient - PUBLIC FILE_SET HEADERS - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/GraphQLClient.h - PUBLIC FILE_SET CXX_MODULES - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/Client.ixx) +target_sources(graphqlclient PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/GraphQLClient.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(graphqlclient PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/Client.ixx) +endif() if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqlclient) @@ -414,17 +402,14 @@ if(GRAPHQL_USE_RAPIDJSON) target_compile_features(graphqljson PUBLIC cxx_std_20) target_link_libraries(graphqljson PUBLIC graphqlresponse) target_include_directories(graphqljson SYSTEM PRIVATE ${RAPIDJSON_INCLUDE_DIRS}) - target_sources(graphqljson - PUBLIC FILE_SET HEADERS - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/JSONResponse.h - PUBLIC FILE_SET CXX_MODULES - BASE_DIRS - ${INCLUDE_ROOT} - FILES - ${INCLUDE_ROOT}/graphqlservice/JSONResponse.ixx) + target_sources(graphqljson PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/JSONResponse.h) + if(GRAPHQL_BUILD_MODULES) + target_sources(graphqljson PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/JSONResponse.ixx) + endif() if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqljson) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9e0a8150..062f2995 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,51 +14,53 @@ target_link_libraries(validation_tests PRIVATE add_bigobj_flag(validation_tests) gtest_add_tests(TARGET validation_tests) -add_executable(today_tests TodayTests.cpp) -target_link_libraries(today_tests PRIVATE - todaygraphql - graphqljson - GTest::GTest - GTest::Main) -add_bigobj_flag(today_tests) -gtest_add_tests(TARGET today_tests) +if(GRAPHQL_BUILD_MODULES) + add_executable(today_tests TodayTests.cpp) + target_link_libraries(today_tests PRIVATE + todaygraphql + graphqljson + GTest::GTest + GTest::Main) + add_bigobj_flag(today_tests) + gtest_add_tests(TARGET today_tests) -add_executable(coroutine_tests CoroutineTests.cpp) -target_link_libraries(coroutine_tests PRIVATE - todaygraphql - graphqljson - GTest::GTest - GTest::Main) -gtest_add_tests(TARGET coroutine_tests) + add_executable(coroutine_tests CoroutineTests.cpp) + target_link_libraries(coroutine_tests PRIVATE + todaygraphql + graphqljson + GTest::GTest + GTest::Main) + gtest_add_tests(TARGET coroutine_tests) -add_executable(client_tests ClientTests.cpp) -target_link_libraries(client_tests PRIVATE - todaygraphql - query_client - mutate_client - subscribe_client - GTest::GTest - GTest::Main) -add_bigobj_flag(client_tests) -gtest_add_tests(TARGET client_tests) + add_executable(client_tests ClientTests.cpp) + target_link_libraries(client_tests PRIVATE + todaygraphql + query_client + mutate_client + subscribe_client + GTest::GTest + GTest::Main) + add_bigobj_flag(client_tests) + gtest_add_tests(TARGET client_tests) -add_executable(nointrospection_tests NoIntrospectionTests.cpp) -target_link_libraries(nointrospection_tests PRIVATE - todaygraphql_nointrospection - graphqljson - GTest::GTest - GTest::Main) -add_bigobj_flag(nointrospection_tests) -gtest_add_tests(TARGET nointrospection_tests) + add_executable(nointrospection_tests NoIntrospectionTests.cpp) + target_link_libraries(nointrospection_tests PRIVATE + todaygraphql_nointrospection + graphqljson + GTest::GTest + GTest::Main) + add_bigobj_flag(nointrospection_tests) + gtest_add_tests(TARGET nointrospection_tests) -add_executable(argument_tests ArgumentTests.cpp) -target_link_libraries(argument_tests PRIVATE - todaygraphql - graphqljson - GTest::GTest - GTest::Main) -add_bigobj_flag(argument_tests) -gtest_add_tests(TARGET argument_tests) + add_executable(argument_tests ArgumentTests.cpp) + target_link_libraries(argument_tests PRIVATE + todaygraphql + graphqljson + GTest::GTest + GTest::Main) + add_bigobj_flag(argument_tests) + gtest_add_tests(TARGET argument_tests) +endif() add_executable(pegtl_combined_tests PegtlCombinedTests.cpp) target_link_libraries(pegtl_combined_tests PRIVATE @@ -118,10 +120,12 @@ if(WIN32 AND BUILD_SHARED_LIBS) add_custom_target(copy_test_dlls DEPENDS copied_test_dlls) add_dependencies(validation_tests copy_test_dlls) - add_dependencies(today_tests copy_test_dlls) - add_dependencies(client_tests copy_test_dlls) - add_dependencies(nointrospection_tests copy_test_dlls) - add_dependencies(argument_tests copy_test_dlls) + if(GRAPHQL_BUILD_MODULES) + add_dependencies(today_tests copy_test_dlls) + add_dependencies(client_tests copy_test_dlls) + add_dependencies(nointrospection_tests copy_test_dlls) + add_dependencies(argument_tests copy_test_dlls) + endif() add_dependencies(pegtl_combined_tests copy_test_dlls) add_dependencies(pegtl_executable_tests copy_test_dlls) add_dependencies(pegtl_schema_tests copy_test_dlls) From 26db35e8c8a43c9b03b271f8ed616ae614633c51 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 22:32:42 -0700 Subject: [PATCH 055/123] fix(ci): reenable macOS CI by disabling modules --- .github/workflows/macos.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 78dae2ec..0f04dd34 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -1,8 +1,6 @@ name: macOS -# Turning off macOS CI build since Apple Clang doesn't support C++20 modules -#on: [push, pull_request] -on: [pull_request] +on: [push, pull_request] jobs: xcode: @@ -19,8 +17,6 @@ jobs: submodules: true fetch-depth: 0 - - uses: seanmiddleditch/gha-setup-ninja@96bed6edff20d1dd61ecff9b75cc519d516e6401 - - name: Cache vcpkg uses: actions/cache@v4.0.2 id: cache-vcpkg @@ -54,8 +50,7 @@ jobs: $cacheAccess = $(if ('${{ steps.cache-vcpkg.outputs.cache-hit }}' -eq 'true') { 'read' } else { 'write' }) $env:VCPKG_BINARY_SOURCES = "clear;files,$cachedBinaries,$cacheAccess" - $env:PATH = "${env:PATH}:${{ github.workspace }}/ninja-build" - cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" -G Ninja ${{ github.workspace }} + cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" "-DGRAPHQL_BUILD_MODULES=OFF" ${{ github.workspace }} - name: Build working-directory: build/ From 763c136e0efcfeb94be4e123c4ad9b06f8b30338 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 22:37:13 -0700 Subject: [PATCH 056/123] fix(ci): switch macOS CI back to Ninja --- .github/workflows/macos.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 0f04dd34..c7d3ef49 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -3,7 +3,7 @@ name: macOS on: [push, pull_request] jobs: - xcode: + apple-clang: strategy: fail-fast: false matrix: @@ -17,6 +17,8 @@ jobs: submodules: true fetch-depth: 0 + - uses: seanmiddleditch/gha-setup-ninja@96bed6edff20d1dd61ecff9b75cc519d516e6401 + - name: Cache vcpkg uses: actions/cache@v4.0.2 id: cache-vcpkg @@ -50,7 +52,8 @@ jobs: $cacheAccess = $(if ('${{ steps.cache-vcpkg.outputs.cache-hit }}' -eq 'true') { 'read' } else { 'write' }) $env:VCPKG_BINARY_SOURCES = "clear;files,$cachedBinaries,$cacheAccess" - cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" "-DGRAPHQL_BUILD_MODULES=OFF" ${{ github.workspace }} + $env:PATH = "${env:PATH}:${{ github.workspace }}/ninja-build" + cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" "-DGRAPHQL_BUILD_MODULES=OFF" -G Ninja ${{ github.workspace }} - name: Build working-directory: build/ From c30fcf12c8c1ea4f43645ada201eee4d0d328924 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 22:43:38 -0700 Subject: [PATCH 057/123] fix(ci): build header only libs as OBJECT instead of STATIC --- src/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c38242e4..64d1d21f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,7 +74,7 @@ endfunction() file(REAL_PATH ../include/ INCLUDE_ROOT) # graphql_internal_modules -add_library(graphql_internal_modules STATIC) +add_library(graphql_internal_modules OBJECT) add_library(cppgraphqlgen::graphql_internal_modules ALIAS graphql_internal_modules) set_target_properties(graphql_internal_modules PROPERTIES LINKER_LANGUAGE CXX) target_compile_features(graphql_internal_modules PUBLIC cxx_std_20) @@ -110,7 +110,7 @@ if(GRAPHQL_BUILD_MODULES) endif() # graphql_introspection_modules -add_library(graphql_introspection_modules STATIC) +add_library(graphql_introspection_modules OBJECT) add_library(cppgraphqlgen::graphql_introspection_modules ALIAS graphql_introspection_modules) set_target_properties(graphql_introspection_modules PROPERTIES LINKER_LANGUAGE CXX) target_compile_features(graphql_introspection_modules PUBLIC cxx_std_20) From b6b829dac9ca22f7de13a7b4efc2886eaa4f725a Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 23:21:38 -0700 Subject: [PATCH 058/123] fix(modules): reexport internal modules referenced in public modules --- include/graphqlservice/Response.ixx | 2 +- include/graphqlservice/Service.ixx | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/graphqlservice/Response.ixx b/include/graphqlservice/Response.ixx index 208368e6..5e4160ce 100644 --- a/include/graphqlservice/Response.ixx +++ b/include/graphqlservice/Response.ixx @@ -7,7 +7,7 @@ module; export module GraphQL.Response; -namespace included = graphql::response; +export import GraphQL.Internal.Awaitable; export namespace graphql::response { diff --git a/include/graphqlservice/Service.ixx b/include/graphqlservice/Service.ixx index 83b88a2f..a7cd01f2 100644 --- a/include/graphqlservice/Service.ixx +++ b/include/graphqlservice/Service.ixx @@ -10,6 +10,9 @@ export module GraphQL.Service; export import GraphQL.Parse; export import GraphQL.Response; +export import GraphQL.Internal.Awaitable; +export import GraphQL.Internal.SortedMap; + export namespace graphql { namespace schema { From 6ab4af002fb16a25e7ffd5a57d512e02259ac542 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 23:31:56 -0700 Subject: [PATCH 059/123] chore(release): update version to 5.0.0 --- cmake/version.txt | 2 +- include/graphqlservice/internal/Version.h | 8 ++++---- .../graphqlservice/introspection/IntrospectionSchema.h | 6 +++--- res/ClientGen.rc | 4 ++-- res/SchemaGen.rc | 4 ++-- res/graphqlclient_version.rc | 4 ++-- res/graphqljson_version.rc | 4 ++-- res/graphqlpeg_version.rc | 4 ++-- res/graphqlresponse_version.rc | 4 ++-- res/graphqlservice_version.rc | 4 ++-- samples/client/benchmark/BenchmarkClient.h | 6 +++--- samples/client/multiple/MultipleQueriesClient.h | 6 +++--- samples/client/mutate/MutateClient.h | 6 +++--- samples/client/nestedinput/NestedInputClient.h | 6 +++--- samples/client/query/QueryClient.h | 6 +++--- samples/client/subscribe/SubscribeClient.h | 6 +++--- samples/learn/schema/StarWarsSchema.h | 6 +++--- samples/today/nointrospection/TodaySchema.h | 6 +++--- samples/today/schema/TodaySchema.h | 6 +++--- samples/validation/schema/ValidationSchema.h | 6 +++--- src/introspection/IntrospectionSchema.h | 6 +++--- 21 files changed, 55 insertions(+), 55 deletions(-) diff --git a/cmake/version.txt b/cmake/version.txt index b544af5f..28cbf7c0 100644 --- a/cmake/version.txt +++ b/cmake/version.txt @@ -1 +1 @@ -4.5.8 \ No newline at end of file +5.0.0 \ No newline at end of file diff --git a/include/graphqlservice/internal/Version.h b/include/graphqlservice/internal/Version.h index 8691f3b4..e99dc41c 100644 --- a/include/graphqlservice/internal/Version.h +++ b/include/graphqlservice/internal/Version.h @@ -13,11 +13,11 @@ namespace graphql::internal { inline namespace version { -constexpr std::string_view FullVersion { "4.5.8" }; +constexpr std::string_view FullVersion { "5.0.0" }; -constexpr std::size_t MajorVersion = 4; -constexpr std::size_t MinorVersion = 5; -constexpr std::size_t PatchVersion = 8; +constexpr std::size_t MajorVersion = 5; +constexpr std::size_t MinorVersion = 0; +constexpr std::size_t PatchVersion = 0; } // namespace version diff --git a/include/graphqlservice/introspection/IntrospectionSchema.h b/include/graphqlservice/introspection/IntrospectionSchema.h index b8e76fe3..b754e4ad 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.h +++ b/include/graphqlservice/introspection/IntrospectionSchema.h @@ -19,9 +19,9 @@ #include #include -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); namespace graphql { namespace introspection { diff --git a/res/ClientGen.rc b/res/ClientGen.rc index 8785c717..5557a731 100644 --- a/res/ClientGen.rc +++ b/res/ClientGen.rc @@ -3,8 +3,8 @@ #include -#define GRAPHQL_RC_VERSION 4,5,8,0 -#define GRAPHQL_RC_VERSION_STR "4.5.8" +#define GRAPHQL_RC_VERSION 5,0,0,0 +#define GRAPHQL_RC_VERSION_STR "5.0.0" #ifndef DEBUG #define VER_DEBUG 0 diff --git a/res/SchemaGen.rc b/res/SchemaGen.rc index 989e484a..9075199f 100644 --- a/res/SchemaGen.rc +++ b/res/SchemaGen.rc @@ -3,8 +3,8 @@ #include -#define GRAPHQL_RC_VERSION 4,5,8,0 -#define GRAPHQL_RC_VERSION_STR "4.5.8" +#define GRAPHQL_RC_VERSION 5,0,0,0 +#define GRAPHQL_RC_VERSION_STR "5.0.0" #ifndef DEBUG #define VER_DEBUG 0 diff --git a/res/graphqlclient_version.rc b/res/graphqlclient_version.rc index 6812db98..99596091 100644 --- a/res/graphqlclient_version.rc +++ b/res/graphqlclient_version.rc @@ -3,8 +3,8 @@ #include -#define GRAPHQL_RC_VERSION 4,5,8,0 -#define GRAPHQL_RC_VERSION_STR "4.5.8" +#define GRAPHQL_RC_VERSION 5,0,0,0 +#define GRAPHQL_RC_VERSION_STR "5.0.0" #ifndef DEBUG #define VER_DEBUG 0 diff --git a/res/graphqljson_version.rc b/res/graphqljson_version.rc index 0de07f82..6abe6dff 100644 --- a/res/graphqljson_version.rc +++ b/res/graphqljson_version.rc @@ -3,8 +3,8 @@ #include -#define GRAPHQL_RC_VERSION 4,5,8,0 -#define GRAPHQL_RC_VERSION_STR "4.5.8" +#define GRAPHQL_RC_VERSION 5,0,0,0 +#define GRAPHQL_RC_VERSION_STR "5.0.0" #ifndef DEBUG #define VER_DEBUG 0 diff --git a/res/graphqlpeg_version.rc b/res/graphqlpeg_version.rc index 46ba5938..a2e61263 100644 --- a/res/graphqlpeg_version.rc +++ b/res/graphqlpeg_version.rc @@ -3,8 +3,8 @@ #include -#define GRAPHQL_RC_VERSION 4,5,8,0 -#define GRAPHQL_RC_VERSION_STR "4.5.8" +#define GRAPHQL_RC_VERSION 5,0,0,0 +#define GRAPHQL_RC_VERSION_STR "5.0.0" #ifndef DEBUG #define VER_DEBUG 0 diff --git a/res/graphqlresponse_version.rc b/res/graphqlresponse_version.rc index 03ae40ec..18389796 100644 --- a/res/graphqlresponse_version.rc +++ b/res/graphqlresponse_version.rc @@ -3,8 +3,8 @@ #include -#define GRAPHQL_RC_VERSION 4,5,8,0 -#define GRAPHQL_RC_VERSION_STR "4.5.8" +#define GRAPHQL_RC_VERSION 5,0,0,0 +#define GRAPHQL_RC_VERSION_STR "5.0.0" #ifndef DEBUG #define VER_DEBUG 0 diff --git a/res/graphqlservice_version.rc b/res/graphqlservice_version.rc index 75da515d..76c0d63a 100644 --- a/res/graphqlservice_version.rc +++ b/res/graphqlservice_version.rc @@ -3,8 +3,8 @@ #include -#define GRAPHQL_RC_VERSION 4,5,8,0 -#define GRAPHQL_RC_VERSION_STR "4.5.8" +#define GRAPHQL_RC_VERSION 5,0,0,0 +#define GRAPHQL_RC_VERSION_STR "5.0.0" #ifndef DEBUG #define VER_DEBUG 0 diff --git a/samples/client/benchmark/BenchmarkClient.h b/samples/client/benchmark/BenchmarkClient.h index 9ba57395..27311125 100644 --- a/samples/client/benchmark/BenchmarkClient.h +++ b/samples/client/benchmark/BenchmarkClient.h @@ -18,9 +18,9 @@ #include #include -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); +// Check if the library version is compatible with clientgen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); namespace graphql::client { diff --git a/samples/client/multiple/MultipleQueriesClient.h b/samples/client/multiple/MultipleQueriesClient.h index e57ad66d..4e3e7634 100644 --- a/samples/client/multiple/MultipleQueriesClient.h +++ b/samples/client/multiple/MultipleQueriesClient.h @@ -18,9 +18,9 @@ #include #include -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); +// Check if the library version is compatible with clientgen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); namespace graphql::client { diff --git a/samples/client/mutate/MutateClient.h b/samples/client/mutate/MutateClient.h index 2fbe3a4a..74870657 100644 --- a/samples/client/mutate/MutateClient.h +++ b/samples/client/mutate/MutateClient.h @@ -18,9 +18,9 @@ #include #include -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); +// Check if the library version is compatible with clientgen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); namespace graphql::client { diff --git a/samples/client/nestedinput/NestedInputClient.h b/samples/client/nestedinput/NestedInputClient.h index d3dd2db2..8a1cf0eb 100644 --- a/samples/client/nestedinput/NestedInputClient.h +++ b/samples/client/nestedinput/NestedInputClient.h @@ -18,9 +18,9 @@ #include #include -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); +// Check if the library version is compatible with clientgen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); namespace graphql::client { diff --git a/samples/client/query/QueryClient.h b/samples/client/query/QueryClient.h index 109ddf5c..23aa0229 100644 --- a/samples/client/query/QueryClient.h +++ b/samples/client/query/QueryClient.h @@ -18,9 +18,9 @@ #include #include -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); +// Check if the library version is compatible with clientgen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); namespace graphql::client { diff --git a/samples/client/subscribe/SubscribeClient.h b/samples/client/subscribe/SubscribeClient.h index e01d433e..495d02a8 100644 --- a/samples/client/subscribe/SubscribeClient.h +++ b/samples/client/subscribe/SubscribeClient.h @@ -18,9 +18,9 @@ #include #include -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); +// Check if the library version is compatible with clientgen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); namespace graphql::client { diff --git a/samples/learn/schema/StarWarsSchema.h b/samples/learn/schema/StarWarsSchema.h index 43d229b4..6191bfdc 100644 --- a/samples/learn/schema/StarWarsSchema.h +++ b/samples/learn/schema/StarWarsSchema.h @@ -19,9 +19,9 @@ #include #include -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); namespace graphql { namespace learn { diff --git a/samples/today/nointrospection/TodaySchema.h b/samples/today/nointrospection/TodaySchema.h index 8128495e..3798db11 100644 --- a/samples/today/nointrospection/TodaySchema.h +++ b/samples/today/nointrospection/TodaySchema.h @@ -19,9 +19,9 @@ #include #include -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); namespace graphql { namespace today { diff --git a/samples/today/schema/TodaySchema.h b/samples/today/schema/TodaySchema.h index 8128495e..3798db11 100644 --- a/samples/today/schema/TodaySchema.h +++ b/samples/today/schema/TodaySchema.h @@ -19,9 +19,9 @@ #include #include -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); namespace graphql { namespace today { diff --git a/samples/validation/schema/ValidationSchema.h b/samples/validation/schema/ValidationSchema.h index 980bba28..9f6be1d3 100644 --- a/samples/validation/schema/ValidationSchema.h +++ b/samples/validation/schema/ValidationSchema.h @@ -19,9 +19,9 @@ #include #include -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); namespace graphql { namespace validation { diff --git a/src/introspection/IntrospectionSchema.h b/src/introspection/IntrospectionSchema.h index b8e76fe3..b754e4ad 100644 --- a/src/introspection/IntrospectionSchema.h +++ b/src/introspection/IntrospectionSchema.h @@ -19,9 +19,9 @@ #include #include -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); namespace graphql { namespace introspection { From 129d69f011fb6e98171d5286cf83b86be6f21da6 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 15 Sep 2024 23:52:03 -0700 Subject: [PATCH 060/123] fix(deps): use updated CMake variables for Boost.Beast detection --- samples/CMakeLists.txt | 20 +++++--------------- samples/proxy/query/ProxyClient.h | 6 +++--- samples/proxy/schema/ProxySchema.h | 6 +++--- samples/proxy/schema/ProxySchema.ixx | 2 +- 4 files changed, 12 insertions(+), 22 deletions(-) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index eff2f4ca..e3a2b1fd 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -13,22 +13,12 @@ endif() if(GRAPHQL_BUILD_HTTP_SAMPLE) find_package(boost_beast CONFIG QUIET) - if(Boost_FOUND) - if(Boost_VERSION VERSION_GREATER_EQUAL "1.81.0") - try_compile(TEST_RESULT - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/test_boost_beast.cpp - CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${Boost_INCLUDE_DIRS} - CXX_STANDARD 20) - - if(TEST_RESULT) - message(STATUS "Using Boost.Beast ${Boost_VERSION}") - add_subdirectory(proxy) - else() - message(WARNING "GRAPHQL_BUILD_HTTP_SAMPLE requires the Boost.Beast header-only library and a toolchain that supports co_await in Boost.Asio.") - endif() + if(boost_beast_FOUND) + if(boost_beast_VERSION VERSION_GREATER_EQUAL "1.81.0") + message(STATUS "Using Boost.Beast ${boost_beast_VERSION}") + add_subdirectory(proxy) else() - message(WARNING "GRAPHQL_BUILD_HTTP_SAMPLE requires the Boost.Beast header-only library >= 1.81.0, but only ${Boost_VERSION} was found in ${Boost_INCLUDE_DIR}.") + message(WARNING "GRAPHQL_BUILD_HTTP_SAMPLE requires the Boost.Beast header-only library >= 1.81.0, but only ${boost_beast_VERSION} was found.") endif() endif() endif() diff --git a/samples/proxy/query/ProxyClient.h b/samples/proxy/query/ProxyClient.h index 6301f8e6..a1464f21 100644 --- a/samples/proxy/query/ProxyClient.h +++ b/samples/proxy/query/ProxyClient.h @@ -18,9 +18,9 @@ #include #include -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); +// Check if the library version is compatible with clientgen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); namespace graphql::client { diff --git a/samples/proxy/schema/ProxySchema.h b/samples/proxy/schema/ProxySchema.h index dbf732ba..77eca72d 100644 --- a/samples/proxy/schema/ProxySchema.h +++ b/samples/proxy/schema/ProxySchema.h @@ -19,9 +19,9 @@ #include #include -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); namespace graphql { namespace proxy { diff --git a/samples/proxy/schema/ProxySchema.ixx b/samples/proxy/schema/ProxySchema.ixx index a8d801b7..274f6963 100644 --- a/samples/proxy/schema/ProxySchema.ixx +++ b/samples/proxy/schema/ProxySchema.ixx @@ -9,7 +9,7 @@ module; export module GraphQL.Proxy.ProxySchema; -namespace included = graphql::proxy; +export import GraphQL.Proxy.QueryObject; export namespace graphql::proxy { From b57272ffe0575d0be7182cf0bad3a9f326988f9f Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 16 Sep 2024 00:02:10 -0700 Subject: [PATCH 061/123] fix(modules): switch to inline namespace in GraphQLParse.h --- include/graphqlservice/GraphQLParse.h | 4 ++++ include/graphqlservice/Parse.ixx | 6 +----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/graphqlservice/GraphQLParse.h b/include/graphqlservice/GraphQLParse.h index 4336fb8e..40cc8749 100644 --- a/include/graphqlservice/GraphQLParse.h +++ b/include/graphqlservice/GraphQLParse.h @@ -25,10 +25,14 @@ struct [[nodiscard("unnecessary parse")]] ast bool validated = false; }; +inline namespace constants { + // By default, we want to limit the depth of nested nodes. You can override this with // another value for the depthLimit parameter in these parse functions. constexpr std::size_t c_defaultDepthLimit = 25; +} // namespace constants + [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT ast parseSchemaString( std::string_view input, std::size_t depthLimit = c_defaultDepthLimit); [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT ast parseSchemaFile( diff --git a/include/graphqlservice/Parse.ixx b/include/graphqlservice/Parse.ixx index bd699cf1..2c696889 100644 --- a/include/graphqlservice/Parse.ixx +++ b/include/graphqlservice/Parse.ixx @@ -16,11 +16,7 @@ using peg::ast_node; using peg::ast_input; using peg::ast; -namespace constants { - -constexpr std::size_t c_defaultDepthLimit = peg::c_defaultDepthLimit; - -} // namespace constants +constexpr std::size_t c_defaultDepthLimit = constants::c_defaultDepthLimit; using peg::parseSchemaString; using peg::parseSchemaFile; From 8bd97b6e2ec1beed7431a64bfacd55018cb6d6ca Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 16 Sep 2024 00:08:28 -0700 Subject: [PATCH 062/123] fix(fmt): cleanup extra blank line in client module interfaces --- samples/client/benchmark/BenchmarkClient.ixx | 1 - .../client/multiple/MultipleQueriesClient.ixx | 1 - samples/client/mutate/MutateClient.ixx | 1 - samples/client/nestedinput/NestedInputClient.ixx | 1 - samples/client/query/QueryClient.ixx | 1 - samples/client/subscribe/SubscribeClient.ixx | 1 - samples/proxy/query/ProxyClient.ixx | 1 - src/ClientGenerator.cpp | 16 ++++++---------- 8 files changed, 6 insertions(+), 17 deletions(-) diff --git a/samples/client/benchmark/BenchmarkClient.ixx b/samples/client/benchmark/BenchmarkClient.ixx index 64b88c5b..0400cf83 100644 --- a/samples/client/benchmark/BenchmarkClient.ixx +++ b/samples/client/benchmark/BenchmarkClient.ixx @@ -11,7 +11,6 @@ export module GraphQL.Benchmark.BenchmarkClient; export namespace graphql::client { - namespace benchmark { using benchmark::GetRequestText; diff --git a/samples/client/multiple/MultipleQueriesClient.ixx b/samples/client/multiple/MultipleQueriesClient.ixx index f2b5ce2d..a12ea9b4 100644 --- a/samples/client/multiple/MultipleQueriesClient.ixx +++ b/samples/client/multiple/MultipleQueriesClient.ixx @@ -11,7 +11,6 @@ export module GraphQL.MultipleQueries.MultipleQueriesClient; export namespace graphql::client { - namespace multiple { using multiple::GetRequestText; diff --git a/samples/client/mutate/MutateClient.ixx b/samples/client/mutate/MutateClient.ixx index 9c4579ee..67b20b6d 100644 --- a/samples/client/mutate/MutateClient.ixx +++ b/samples/client/mutate/MutateClient.ixx @@ -11,7 +11,6 @@ export module GraphQL.Mutate.MutateClient; export namespace graphql::client { - namespace mutate { using mutate::GetRequestText; diff --git a/samples/client/nestedinput/NestedInputClient.ixx b/samples/client/nestedinput/NestedInputClient.ixx index fe02a9a8..c7f1253b 100644 --- a/samples/client/nestedinput/NestedInputClient.ixx +++ b/samples/client/nestedinput/NestedInputClient.ixx @@ -11,7 +11,6 @@ export module GraphQL.NestedInput.NestedInputClient; export namespace graphql::client { - namespace nestedinput { using nestedinput::GetRequestText; diff --git a/samples/client/query/QueryClient.ixx b/samples/client/query/QueryClient.ixx index f4d077ef..97f91145 100644 --- a/samples/client/query/QueryClient.ixx +++ b/samples/client/query/QueryClient.ixx @@ -11,7 +11,6 @@ export module GraphQL.Query.QueryClient; export namespace graphql::client { - namespace query { using query::GetRequestText; diff --git a/samples/client/subscribe/SubscribeClient.ixx b/samples/client/subscribe/SubscribeClient.ixx index adeae8ed..cf92a734 100644 --- a/samples/client/subscribe/SubscribeClient.ixx +++ b/samples/client/subscribe/SubscribeClient.ixx @@ -11,7 +11,6 @@ export module GraphQL.Subscribe.SubscribeClient; export namespace graphql::client { - namespace subscribe { using subscribe::GetRequestText; diff --git a/samples/proxy/query/ProxyClient.ixx b/samples/proxy/query/ProxyClient.ixx index 65b38f32..e74294c1 100644 --- a/samples/proxy/query/ProxyClient.ixx +++ b/samples/proxy/query/ProxyClient.ixx @@ -11,7 +11,6 @@ export module GraphQL.Proxy.ProxyClient; export namespace graphql::client { - namespace proxy { using proxy::GetRequestText; diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index e3bca07d..ad01d3a1 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -643,20 +643,15 @@ export )cpp"; moduleFile << std::endl; - NamespaceScope schemaNamespace { moduleFile, _schemaLoader.getSchemaNamespace(), true }; + NamespaceScope schemaNamespace { moduleFile, _schemaLoader.getSchemaNamespace() }; PendingBlankLine pendingSeparator { moduleFile }; - pendingSeparator.reset(); - if (schemaNamespace.enter()) - { - moduleFile << R"cpp( + moduleFile << R"cpp( using )cpp" << _schemaLoader.getSchemaNamespace() - << R"cpp(::GetRequestText; + << R"cpp(::GetRequestText; using )cpp" << _schemaLoader.getSchemaNamespace() - << R"cpp(::GetRequestObject; + << R"cpp(::GetRequestObject; )cpp"; - pendingSeparator.add(); - } const auto& operations = _requestLoader.getOperations(); std::unordered_set declaredEnum; @@ -1065,7 +1060,8 @@ response::Value Variable<)cpp" sourceFile << R"cpp(template <> response::Value Variable<)cpp" - << cppType << R"cpp(>::serialize()cpp" << cppType << R"cpp(&& inputValue) + << cppType << R"cpp(>::serialize()cpp" << cppType + << R"cpp(&& inputValue) { response::Value result { response::Type::Map }; From 20057dd1a66c1b69cbb25ff0bb6d4b1f883ad057 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 16 Sep 2024 08:56:55 -0700 Subject: [PATCH 063/123] fix(cmake): propagate GRAPHQL_BUILD_MODULES to consumers as target props --- cmake/cppgraphqlgen-functions.cmake | 2 ++ src/CMakeLists.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/cmake/cppgraphqlgen-functions.cmake b/cmake/cppgraphqlgen-functions.cmake index 5114c6b7..3b5d1615 100644 --- a/cmake/cppgraphqlgen-functions.cmake +++ b/cmake/cppgraphqlgen-functions.cmake @@ -53,6 +53,7 @@ function(add_graphql_schema_target SCHEMA_TARGET) target_sources(${SCHEMA_TARGET}_schema PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SCHEMA_HEADERS}) + get_target_property(GRAPHQL_BUILD_MODULES cppgraphqlgen::graphqlservice GRAPHQL_BUILD_MODULES) if(GRAPHQL_BUILD_MODULES) file(GLOB SCHEMA_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) target_sources(${SCHEMA_TARGET}_schema PUBLIC FILE_SET CXX_MODULES @@ -106,6 +107,7 @@ function(add_graphql_client_target CLIENT_TARGET) target_sources(${CLIENT_TARGET}_client PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES ${CLIENT_HEADERS}) + get_target_property(GRAPHQL_BUILD_MODULES cppgraphqlgen::graphqlclient GRAPHQL_BUILD_MODULES) if(GRAPHQL_BUILD_MODULES) file(GLOB CLIENT_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) target_sources(${CLIENT_TARGET}_client PUBLIC FILE_SET CXX_MODULES diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64d1d21f..307a9325 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -337,6 +337,7 @@ if(GRAPHQL_BUILD_MODULES) target_sources(graphqlservice PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${INCLUDE_ROOT} FILES ${INCLUDE_ROOT}/graphqlservice/Service.ixx) + set_target_properties(graphqlservice PROPERTIES GRAPHQL_BUILD_MODULES ON) endif() if(GRAPHQL_UPDATE_SAMPLES) @@ -373,6 +374,7 @@ if(GRAPHQL_BUILD_MODULES) target_sources(graphqlclient PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${INCLUDE_ROOT} FILES ${INCLUDE_ROOT}/graphqlservice/Client.ixx) + set_target_properties(graphqlclient PROPERTIES GRAPHQL_BUILD_MODULES ON) endif() if(GRAPHQL_UPDATE_VERSION) From 67b56d8c1c9c083ffc3ac38dd84761edc4ee591b Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 16 Sep 2024 09:08:45 -0700 Subject: [PATCH 064/123] fix(ci): switch macOS build back to xcode --- .github/workflows/macos.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index c7d3ef49..0f04dd34 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -3,7 +3,7 @@ name: macOS on: [push, pull_request] jobs: - apple-clang: + xcode: strategy: fail-fast: false matrix: @@ -17,8 +17,6 @@ jobs: submodules: true fetch-depth: 0 - - uses: seanmiddleditch/gha-setup-ninja@96bed6edff20d1dd61ecff9b75cc519d516e6401 - - name: Cache vcpkg uses: actions/cache@v4.0.2 id: cache-vcpkg @@ -52,8 +50,7 @@ jobs: $cacheAccess = $(if ('${{ steps.cache-vcpkg.outputs.cache-hit }}' -eq 'true') { 'read' } else { 'write' }) $env:VCPKG_BINARY_SOURCES = "clear;files,$cachedBinaries,$cacheAccess" - $env:PATH = "${env:PATH}:${{ github.workspace }}/ninja-build" - cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" "-DGRAPHQL_BUILD_MODULES=OFF" -G Ninja ${{ github.workspace }} + cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" "-DGRAPHQL_BUILD_MODULES=OFF" ${{ github.workspace }} - name: Build working-directory: build/ From 2d8ea000ab45c6dc62e917c1da3636a80963a8d3 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 16 Sep 2024 10:04:09 -0700 Subject: [PATCH 065/123] fix(cmake): installed targets don't preserve target properties --- cmake/cppgraphqlgen-functions.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/cppgraphqlgen-functions.cmake b/cmake/cppgraphqlgen-functions.cmake index 3b5d1615..f17a1ff0 100644 --- a/cmake/cppgraphqlgen-functions.cmake +++ b/cmake/cppgraphqlgen-functions.cmake @@ -53,7 +53,7 @@ function(add_graphql_schema_target SCHEMA_TARGET) target_sources(${SCHEMA_TARGET}_schema PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SCHEMA_HEADERS}) - get_target_property(GRAPHQL_BUILD_MODULES cppgraphqlgen::graphqlservice GRAPHQL_BUILD_MODULES) + get_target_property(GRAPHQL_BUILD_MODULES cppgraphqlgen::graphqlservice INTERFACE_CXX_MODULE_SETS) if(GRAPHQL_BUILD_MODULES) file(GLOB SCHEMA_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) target_sources(${SCHEMA_TARGET}_schema PUBLIC FILE_SET CXX_MODULES @@ -107,7 +107,7 @@ function(add_graphql_client_target CLIENT_TARGET) target_sources(${CLIENT_TARGET}_client PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES ${CLIENT_HEADERS}) - get_target_property(GRAPHQL_BUILD_MODULES cppgraphqlgen::graphqlclient GRAPHQL_BUILD_MODULES) + get_target_property(GRAPHQL_BUILD_MODULES cppgraphqlgen::graphqlclient INTERFACE_CXX_MODULE_SETS) if(GRAPHQL_BUILD_MODULES) file(GLOB CLIENT_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) target_sources(${CLIENT_TARGET}_client PUBLIC FILE_SET CXX_MODULES From 87258e02ed287db4503734a69f08b0b6e57c41d1 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 16 Sep 2024 10:12:11 -0700 Subject: [PATCH 066/123] fix(cmake): drop unnecessary set_target_properties --- src/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 307a9325..64d1d21f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -337,7 +337,6 @@ if(GRAPHQL_BUILD_MODULES) target_sources(graphqlservice PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${INCLUDE_ROOT} FILES ${INCLUDE_ROOT}/graphqlservice/Service.ixx) - set_target_properties(graphqlservice PROPERTIES GRAPHQL_BUILD_MODULES ON) endif() if(GRAPHQL_UPDATE_SAMPLES) @@ -374,7 +373,6 @@ if(GRAPHQL_BUILD_MODULES) target_sources(graphqlclient PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${INCLUDE_ROOT} FILES ${INCLUDE_ROOT}/graphqlservice/Client.ixx) - set_target_properties(graphqlclient PROPERTIES GRAPHQL_BUILD_MODULES ON) endif() if(GRAPHQL_UPDATE_VERSION) From 7c3e3a8beb0b27e2e8eef084333956bc48a504e1 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 16 Sep 2024 15:36:34 -0700 Subject: [PATCH 067/123] feat(ranges): start adopting ranges --- include/graphqlservice/GraphQLClient.h | 8 +-- include/graphqlservice/GraphQLService.h | 7 ++- samples/client/benchmark.cpp | 3 +- samples/learn/DroidData.cpp | 39 +++++-------- samples/learn/HumanData.cpp | 39 +++++-------- samples/today/TodayMock.cpp | 66 ++++++++-------------- samples/today/benchmark.cpp | 3 +- src/ClientGenerator.cpp | 11 ++-- src/GeneratorUtil.cpp | 20 +++---- src/GraphQLClient.cpp | 9 +-- src/GraphQLResponse.cpp | 12 ++-- src/GraphQLService.cpp | 23 +++----- src/Introspection.cpp | 27 ++++----- src/RequestLoader.cpp | 75 ++++++++++--------------- src/Schema.cpp | 9 +-- src/SchemaGenerator.cpp | 15 ++--- src/SchemaLoader.cpp | 30 +++++----- src/Validation.cpp | 3 +- test/ResponseTests.cpp | 4 +- 19 files changed, 166 insertions(+), 237 deletions(-) diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index afc0caa2..a1f5b5d7 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -167,7 +168,7 @@ struct ModifiedVariable response::Value result { response::Type::List }; result.reserve(listValue.size()); - std::for_each(listValue.begin(), listValue.end(), [&result](auto& value) { + std::ranges::for_each(listValue, [&result](auto& value) { result.emplace_back(serialize(std::move(value))); }); listValue.clear(); @@ -218,7 +219,7 @@ struct ModifiedVariable { typename VariableTraits::type result(listValue.size()); - std::transform(listValue.cbegin(), listValue.cend(), result.begin(), duplicate); + std::ranges::transform(listValue, result.begin(), duplicate); return result; } @@ -322,8 +323,7 @@ struct ModifiedResponse auto listValue = response.release(); result.reserve(listValue.size()); - std::transform(listValue.begin(), - listValue.end(), + std::ranges::transform(listValue, std::back_inserter(result), [](response::Value& value) { return parse(std::move(value)); diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 9561eb86..b6c84687 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -758,8 +759,8 @@ struct ModifiedArgument typename ArgumentTraits::type result(values.size()); const auto& elements = values.get(); - std::transform(elements.cbegin(), - elements.cend(), + std::transform(elements.begin(), + elements.end(), result.begin(), [name](const response::Value& element) { response::Value single(response::Type::Map); @@ -831,7 +832,7 @@ struct ModifiedArgument { typename ArgumentTraits::type result(listValue.size()); - std::transform(listValue.cbegin(), listValue.cend(), result.begin(), duplicate); + std::ranges::transform(listValue, result.begin(), duplicate); return result; } diff --git a/samples/client/benchmark.cpp b/samples/client/benchmark.cpp index 10c56b13..73ce8780 100644 --- a/samples/client/benchmark.cpp +++ b/samples/client/benchmark.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,7 @@ void outputOverview( void outputSegment( std::string_view name, std::vector& durations) noexcept { - std::sort(durations.begin(), durations.end()); + std::ranges::sort(durations); const auto count = durations.size(); const auto total = diff --git a/samples/learn/DroidData.cpp b/samples/learn/DroidData.cpp index ee3d9548..2f40ed22 100644 --- a/samples/learn/DroidData.cpp +++ b/samples/learn/DroidData.cpp @@ -21,18 +21,15 @@ void Droid::addFriends( { friends_.resize(friends.size()); - std::transform(friends.begin(), - friends.end(), - friends_.begin(), - [](const auto& spFriend) noexcept { - return std::visit( - [](const auto& hero) noexcept { - return WeakHero { - std::weak_ptr::element_type> { hero } - }; - }, - spFriend); - }); + std::ranges::transform(friends, friends_.begin(), [](const auto& spFriend) noexcept { + return std::visit( + [](const auto& hero) noexcept { + return WeakHero { + std::weak_ptr::element_type> { hero } + }; + }, + spFriend); + }); } const response::IdType& Droid::getId() const noexcept @@ -49,12 +46,9 @@ std::optional>> Droid::getFriends { std::vector> result(friends_.size()); - std::transform(friends_.begin(), - friends_.end(), - result.begin(), - [](const auto& wpFriend) noexcept { - return make_hero(wpFriend); - }); + std::ranges::transform(friends_, result.begin(), [](const auto& wpFriend) noexcept { + return make_hero(wpFriend); + }); result.erase(std::remove(result.begin(), result.end(), std::shared_ptr {}), result.end()); @@ -65,12 +59,9 @@ std::optional>> Droid::getAppearsIn() const n { std::vector> result(appearsIn_.size()); - std::transform(appearsIn_.begin(), - appearsIn_.end(), - result.begin(), - [](const auto& entry) noexcept { - return std::make_optional(entry); - }); + std::ranges::transform(appearsIn_, result.begin(), [](const auto& entry) noexcept { + return std::make_optional(entry); + }); return result.empty() ? std::nullopt : std::make_optional(std::move(result)); } diff --git a/samples/learn/HumanData.cpp b/samples/learn/HumanData.cpp index 486ce9aa..b9489763 100644 --- a/samples/learn/HumanData.cpp +++ b/samples/learn/HumanData.cpp @@ -20,18 +20,15 @@ void Human::addFriends(std::vector friends) noexcept { friends_.resize(friends.size()); - std::transform(friends.begin(), - friends.end(), - friends_.begin(), - [](const auto& spFriend) noexcept { - return std::visit( - [](const auto& hero) noexcept { - return WeakHero { - std::weak_ptr::element_type> { hero } - }; - }, - spFriend); - }); + std::ranges::transform(friends, friends_.begin(), [](const auto& spFriend) noexcept { + return std::visit( + [](const auto& hero) noexcept { + return WeakHero { + std::weak_ptr::element_type> { hero } + }; + }, + spFriend); + }); } const response::IdType& Human::getId() const noexcept @@ -48,12 +45,9 @@ std::optional>> Human::getFriends { std::vector> result(friends_.size()); - std::transform(friends_.begin(), - friends_.end(), - result.begin(), - [](const auto& wpFriend) noexcept { - return make_hero(wpFriend); - }); + std::ranges::transform(friends_, result.begin(), [](const auto& wpFriend) noexcept { + return make_hero(wpFriend); + }); result.erase(std::remove(result.begin(), result.end(), std::shared_ptr {}), result.end()); @@ -64,12 +58,9 @@ std::optional>> Human::getAppearsIn() const n { std::vector> result(appearsIn_.size()); - std::transform(appearsIn_.begin(), - appearsIn_.end(), - result.begin(), - [](const auto& entry) noexcept { - return std::make_optional(entry); - }); + std::ranges::transform(appearsIn_, result.begin(), [](const auto& entry) noexcept { + return std::make_optional(entry); + }); return result.empty() ? std::nullopt : std::make_optional(std::move(result)); } diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index 53b0b35b..d7464511 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace graphql::today { @@ -24,7 +25,7 @@ const response::IdType& getFakeAppointmentId() noexcept std::string_view fakeIdString { "fakeAppointmentId" }; response::IdType result(fakeIdString.size()); - std::copy(fakeIdString.cbegin(), fakeIdString.cend(), result.begin()); + std::ranges::copy(fakeIdString, result.begin()); return response::IdType { std::move(result) }; }(); @@ -38,7 +39,7 @@ const response::IdType& getFakeTaskId() noexcept std::string_view fakeIdString { "fakeTaskId" }; response::IdType result(fakeIdString.size()); - std::copy(fakeIdString.cbegin(), fakeIdString.cend(), result.begin()); + std::ranges::copy(fakeIdString, result.begin()); return response::IdType { std::move(result) }; }(); @@ -52,7 +53,7 @@ const response::IdType& getFakeFolderId() noexcept std::string_view fakeIdString { "fakeFolderId" }; response::IdType result(fakeIdString.size()); - std::copy(fakeIdString.cbegin(), fakeIdString.cend(), result.begin()); + std::ranges::copy(fakeIdString, result.begin()); return response::IdType { std::move(result) }; }(); @@ -198,8 +199,7 @@ std::optional>> Appointment auto result = std::make_optional>>( _appointments.size()); - std::transform(_appointments.cbegin(), - _appointments.cend(), + std::ranges::transform(_appointments, result->begin(), [](const std::shared_ptr& node) { return std::make_shared( @@ -268,12 +268,9 @@ std::optional>> TaskConnection::ge { auto result = std::make_optional>>(_tasks.size()); - std::transform(_tasks.cbegin(), - _tasks.cend(), - result->begin(), - [](const std::shared_ptr& node) { - return std::make_shared(std::make_shared(node)); - }); + std::ranges::transform(_tasks, result->begin(), [](const std::shared_ptr& node) { + return std::make_shared(std::make_shared(node)); + }); return result; } @@ -338,12 +335,9 @@ std::optional>> FolderConnection auto result = std::make_optional>>(_folders.size()); - std::transform(_folders.cbegin(), - _folders.cend(), - result->begin(), - [](const std::shared_ptr& node) { - return std::make_shared(std::make_shared(node)); - }); + std::ranges::transform(_folders, result->begin(), [](const std::shared_ptr& node) { + return std::make_shared(std::make_shared(node)); + }); return result; } @@ -708,12 +702,9 @@ std::vector> Query::getAppointmentsById( { std::vector> result(ids.size()); - std::transform(ids.cbegin(), - ids.cend(), - result.begin(), - [this, ¶ms](const response::IdType& id) { - return std::make_shared(findAppointment(params, id)); - }); + std::ranges::transform(ids, result.begin(), [this, ¶ms](const response::IdType& id) { + return std::make_shared(findAppointment(params, id)); + }); return result; } @@ -723,12 +714,9 @@ std::vector> Query::getTasksById( { std::vector> result(ids.size()); - std::transform(ids.cbegin(), - ids.cend(), - result.begin(), - [this, ¶ms](const response::IdType& id) { - return std::make_shared(findTask(params, id)); - }); + std::ranges::transform(ids, result.begin(), [this, ¶ms](const response::IdType& id) { + return std::make_shared(findTask(params, id)); + }); return result; } @@ -738,12 +726,9 @@ std::vector> Query::getUnreadCountsById( { std::vector> result(ids.size()); - std::transform(ids.cbegin(), - ids.cend(), - result.begin(), - [this, ¶ms](const response::IdType& id) { - return std::make_shared(findUnreadCount(params, id)); - }); + std::ranges::transform(ids, result.begin(), [this, ¶ms](const response::IdType& id) { + return std::make_shared(findUnreadCount(params, id)); + }); return result; } @@ -777,13 +762,10 @@ std::vector> Query::getAnyType( std::vector> result(_appointments.size()); - std::transform(_appointments.cbegin(), - _appointments.cend(), - result.begin(), - [](const auto& appointment) noexcept { - return std::make_shared( - std::make_shared(appointment)); - }); + std::ranges::transform(_appointments, result.begin(), [](const auto& appointment) noexcept { + return std::make_shared( + std::make_shared(appointment)); + }); return result; } diff --git a/samples/today/benchmark.cpp b/samples/today/benchmark.cpp index bec9c86d..4442135c 100644 --- a/samples/today/benchmark.cpp +++ b/samples/today/benchmark.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -43,7 +44,7 @@ void outputOverview( void outputSegment( std::string_view name, std::vector& durations) noexcept { - std::sort(durations.begin(), durations.end()); + std::ranges::sort(durations); const auto count = durations.size(); const auto total = diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index ad01d3a1..5b472775 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -1120,18 +1120,15 @@ response::Value Variable<)cpp" std::vector> sortedValues( enumValues.size()); - std::transform(enumValues.cbegin(), - enumValues.cend(), + std::ranges::transform(enumValues, sortedValues.begin(), [](const auto& value) noexcept { return std::make_pair(value->name(), SchemaLoader::getSafeCppName(value->name())); }); - std::sort(sortedValues.begin(), - sortedValues.end(), - [](const auto& lhs, const auto& rhs) noexcept { - return internal::shorter_or_less {}(lhs.first, rhs.first); - }); + std::ranges::sort(sortedValues, [](const auto& lhs, const auto& rhs) noexcept { + return internal::shorter_or_less {}(lhs.first, rhs.first); + }); bool firstValue = true; diff --git a/src/GeneratorUtil.cpp b/src/GeneratorUtil.cpp index 8e3acaaf..131370c9 100644 --- a/src/GeneratorUtil.cpp +++ b/src/GeneratorUtil.cpp @@ -4,6 +4,7 @@ #include "GeneratorUtil.h" #include +#include namespace graphql::generator { @@ -12,17 +13,14 @@ IncludeGuardScope::IncludeGuardScope( : _outputFile(outputFile) , _includeGuardName(headerFileName.size(), char {}) { - std::transform(headerFileName.begin(), - headerFileName.end(), - _includeGuardName.begin(), - [](char ch) noexcept -> char { - if (ch == '.') - { - return '_'; - } - - return static_cast(std::toupper(ch)); - }); + std::ranges::transform(headerFileName, _includeGuardName.begin(), [](char ch) noexcept -> char { + if (ch == '.') + { + return '_'; + } + + return static_cast(std::toupper(ch)); + }); _outputFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. diff --git a/src/GraphQLClient.cpp b/src/GraphQLClient.cpp index f56b0a24..b146f018 100644 --- a/src/GraphQLClient.cpp +++ b/src/GraphQLClient.cpp @@ -92,8 +92,7 @@ Error parseServiceError(response::Value&& error) auto locations = member.second.release(); result.locations.reserve(locations.size()); - std::transform(locations.begin(), - locations.end(), + std::ranges::transform(locations, std::back_inserter(result.locations), [](response::Value& location) { return parseServiceErrorLocation(std::move(location)); @@ -110,8 +109,7 @@ Error parseServiceError(response::Value&& error) auto segments = member.second.release(); result.path.reserve(segments.size()); - std::transform(segments.begin(), - segments.end(), + std::ranges::transform(segments, std::back_inserter(result.path), [](response::Value& segment) { return parseServiceErrorPathSegment(std::move(segment)); @@ -150,8 +148,7 @@ ServiceResponse parseServiceResponse(response::Value response) auto errors = member.second.release(); result.errors.reserve(errors.size()); - std::transform(errors.begin(), - errors.end(), + std::ranges::transform(errors, std::back_inserter(result.errors), [](response::Value& error) { return parseServiceError(std::move(error)); diff --git a/src/GraphQLResponse.cpp b/src/GraphQLResponse.cpp index 25b4ba56..d04a3bf3 100644 --- a/src/GraphQLResponse.cpp +++ b/src/GraphQLResponse.cpp @@ -100,9 +100,9 @@ bool IdType::operator==(const IdType& rhs) const noexcept return (std::holds_alternative(_data) ? internal::Base64::compareBase64(std::get(_data), - std::get(rhs._data)) + std::get(rhs._data)) : internal::Base64::compareBase64(std::get(rhs._data), - std::get(_data))) + std::get(_data))) == internal::Base64::Comparison::EqualTo; } @@ -145,7 +145,7 @@ bool IdType::operator<(const IdType& rhs) const noexcept return (std::holds_alternative(_data) ? (internal::Base64::compareBase64(std::get(_data), std::get(rhs._data)) - < internal::Base64::Comparison::EqualTo) + < internal::Base64::Comparison::EqualTo) : (internal::Base64::compareBase64(std::get(rhs._data), std::get(_data))) > internal::Base64::Comparison::EqualTo); @@ -1338,8 +1338,7 @@ bool Value::emplace_back(std::string&& name, Value&& value) } auto& mapData = std::get(_data); - const auto [itr, itrEnd] = std::equal_range(mapData.members.cbegin(), - mapData.members.cend(), + const auto [itr, itrEnd] = std::ranges::equal_range(mapData.members, std::nullopt, [&mapData, &name](std::optional lhs, std::optional rhs) noexcept { std::string_view lhsName { lhs == std::nullopt ? name : mapData.map[*lhs].first }; @@ -1368,8 +1367,7 @@ MapType::const_iterator Value::find(std::string_view name) const } const auto& mapData = std::get(typeData); - const auto [itr, itrEnd] = std::equal_range(mapData.members.cbegin(), - mapData.members.cend(), + const auto [itr, itrEnd] = std::ranges::equal_range(mapData.members, std::nullopt, [&mapData, name](std::optional lhs, std::optional rhs) noexcept { std::string_view lhsName { lhs == std::nullopt ? name : mapData.map[*lhs].first }; diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index af87a2c3..39b74479 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -86,8 +86,7 @@ error_path buildErrorPath(const std::optional& path) } result.reserve(segments.size()); - std::transform(segments.cbegin(), - segments.cend(), + std::ranges::transform(segments, std::back_inserter(result), [](const auto& segment) noexcept { return segment.get(); @@ -133,12 +132,9 @@ std::list schema_exception::convertMessages( { std::list errors; - std::transform(messages.begin(), - messages.end(), - std::back_inserter(errors), - [](std::string& message) noexcept { - return schema_error { std::move(message) }; - }); + std::ranges::transform(messages, std::back_inserter(errors), [](std::string& message) noexcept { + return schema_error { std::move(message) }; + }); return errors; } @@ -254,7 +250,7 @@ void await_worker_queue::resumePending() // Default to immediate synchronous execution. await_async::await_async() : _pimpl { std::static_pointer_cast( - std::make_shared>(std::make_shared())) } + std::make_shared>(std::make_shared())) } { } @@ -262,9 +258,9 @@ await_async::await_async() await_async::await_async(std::launch launch) : _pimpl { ((launch & std::launch::async) == std::launch::async) ? std::static_pointer_cast(std::make_shared>( - std::make_shared())) + std::make_shared())) : std::static_pointer_cast(std::make_shared>( - std::make_shared())) } + std::make_shared())) } { } @@ -1287,7 +1283,7 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, if (!errors.empty()) { - std::copy(errors.begin(), errors.end(), std::back_inserter(document.errors)); + std::ranges::copy(errors, std::back_inserter(document.errors)); } document.data.emplace_back(std::string { child.name }, {}); @@ -2170,8 +2166,7 @@ std::vector> Request::collectRegistratio { // Return all of the registered subscriptions for this field. registrations.reserve(itrListeners->second.size()); - std::transform(itrListeners->second.begin(), - itrListeners->second.end(), + std::ranges::transform(itrListeners->second, std::back_inserter(registrations), [this](const auto& key) noexcept { const auto itr = _subscriptions.find(key); diff --git a/src/Introspection.cpp b/src/Introspection.cpp index 5ac539e9..06bfb9cd 100644 --- a/src/Introspection.cpp +++ b/src/Introspection.cpp @@ -31,7 +31,7 @@ std::vector> Schema::getTypes() const const auto& types = _schema->types(); std::vector> result(types.size()); - std::transform(types.begin(), types.end(), result.begin(), [](const auto& entry) { + std::ranges::transform(types, result.begin(), [](const auto& entry) { return std::make_shared(std::make_shared(entry.second)); }); @@ -67,7 +67,7 @@ std::vector> Schema::getDirectives() const const auto& directives = _schema->directives(); std::vector> result(directives.size()); - std::transform(directives.begin(), directives.end(), result.begin(), [](const auto& entry) { + std::ranges::transform(directives, result.begin(), [](const auto& entry) { return std::make_shared(std::make_shared(entry)); }); @@ -141,7 +141,7 @@ std::optional>> Type::getInterfaces() const auto& interfaces = _type->interfaces(); auto result = std::make_optional>>(interfaces.size()); - std::transform(interfaces.begin(), interfaces.end(), result->begin(), [](const auto& entry) { + std::ranges::transform(interfaces, result->begin(), [](const auto& entry) { return std::make_shared(std::make_shared(entry)); }); @@ -164,16 +164,13 @@ std::optional>> Type::getPossibleTypes auto result = std::make_optional>>(possibleTypes.size()); - std::transform(possibleTypes.begin(), - possibleTypes.end(), - result->begin(), - [](const auto& entry) { - auto typeEntry = entry.lock(); + std::ranges::transform(possibleTypes, result->begin(), [](const auto& entry) { + auto typeEntry = entry.lock(); - return typeEntry && typeEntry->kind() == introspection::TypeKind::OBJECT - ? std::make_shared(std::make_shared(std::move(typeEntry))) - : std::shared_ptr {}; - }); + return typeEntry && typeEntry->kind() == introspection::TypeKind::OBJECT + ? std::make_shared(std::make_shared(std::move(typeEntry))) + : std::shared_ptr {}; + }); result->erase(std::remove(result->begin(), result->end(), std::shared_ptr {}), result->cend()); @@ -225,7 +222,7 @@ std::optional>> Type::getInputFi auto result = std::make_optional>>(inputFields.size()); - std::transform(inputFields.begin(), inputFields.end(), result->begin(), [](const auto& entry) { + std::ranges::transform(inputFields, result->begin(), [](const auto& entry) { return std::make_shared(std::make_shared(entry)); }); @@ -279,7 +276,7 @@ std::vector> Field::getArgs() const const auto& args = _field->args(); std::vector> result(args.size()); - std::transform(args.begin(), args.end(), result.begin(), [](const auto& entry) { + std::ranges::transform(args, result.begin(), [](const auto& entry) { return std::make_shared(std::make_shared(entry)); }); @@ -394,7 +391,7 @@ std::vector> Directive::getArgs() const const auto& args = _directive->args(); std::vector> result(args.size()); - std::transform(args.begin(), args.end(), result.begin(), [](const auto& entry) { + std::ranges::transform(args, result.begin(), [](const auto& entry) { return std::make_shared(std::make_shared(entry)); }); diff --git a/src/RequestLoader.cpp b/src/RequestLoader.cpp index 44d2a47b..2673c707 100644 --- a/src/RequestLoader.cpp +++ b/src/RequestLoader.cpp @@ -418,8 +418,7 @@ void RequestLoader::addTypesToSchema() { std::vector values(enumType.values.size()); - std::transform(enumType.values.cbegin(), - enumType.values.cend(), + std::ranges::transform(enumType.values, values.begin(), [](const EnumValueType& value) noexcept { return schema::EnumValueType { @@ -441,8 +440,7 @@ void RequestLoader::addTypesToSchema() { std::vector> fields(inputType.fields.size()); - std::transform(inputType.fields.cbegin(), - inputType.fields.cend(), + std::ranges::transform(inputType.fields, fields.begin(), [this](const InputField& field) noexcept { return schema::InputValue::Make(field.name, @@ -463,8 +461,7 @@ void RequestLoader::addTypesToSchema() { std::vector> options(unionType.options.size()); - std::transform(unionType.options.cbegin(), - unionType.options.cend(), + std::ranges::transform(unionType.options, options.begin(), [this](std::string_view option) noexcept { return _schema->LookupType(option); @@ -482,15 +479,13 @@ void RequestLoader::addTypesToSchema() { std::vector> fields(interfaceType.fields.size()); - std::transform(interfaceType.fields.cbegin(), - interfaceType.fields.cend(), + std::ranges::transform(interfaceType.fields, fields.begin(), [this](const OutputField& field) noexcept { std::vector> arguments( field.arguments.size()); - std::transform(field.arguments.cbegin(), - field.arguments.cend(), + std::ranges::transform(field.arguments, arguments.begin(), [this](const InputField& argument) noexcept { return schema::InputValue::Make(argument.name, @@ -519,8 +514,7 @@ void RequestLoader::addTypesToSchema() std::vector> interfaces( objectType.interfaces.size()); - std::transform(objectType.interfaces.cbegin(), - objectType.interfaces.cend(), + std::ranges::transform(objectType.interfaces, interfaces.begin(), [&interfaceTypes](std::string_view interfaceName) noexcept { return interfaceTypes[interfaceName]; @@ -533,15 +527,13 @@ void RequestLoader::addTypesToSchema() { std::vector> fields(objectType.fields.size()); - std::transform(objectType.fields.cbegin(), - objectType.fields.cend(), + std::ranges::transform(objectType.fields, fields.begin(), [this](const OutputField& field) noexcept { std::vector> arguments( field.arguments.size()); - std::transform(field.arguments.cbegin(), - field.arguments.cend(), + std::ranges::transform(field.arguments, arguments.begin(), [this](const InputField& argument) noexcept { return schema::InputValue::Make(argument.name, @@ -565,8 +557,7 @@ void RequestLoader::addTypesToSchema() { std::vector locations(directive.locations.size()); - std::transform(directive.locations.cbegin(), - directive.locations.cend(), + std::ranges::transform(directive.locations, locations.begin(), [](std::string_view locationName) noexcept { response::Value locationValue(response::Type::EnumValue); @@ -579,8 +570,7 @@ void RequestLoader::addTypesToSchema() std::vector> arguments( directive.arguments.size()); - std::transform(directive.arguments.cbegin(), - directive.arguments.cend(), + std::ranges::transform(directive.arguments, arguments.begin(), [this](const InputField& argument) noexcept { return schema::InputValue::Make(argument.name, @@ -624,11 +614,11 @@ RequestSchemaType RequestLoader::getSchemaType( { bool nonNull = true; - for (auto itr = modifiers.crbegin(); itr != modifiers.crend(); ++itr) + for (const auto modifier : std::views::all(modifiers) | std::views::reverse) { if (nonNull) { - switch (*itr) + switch (modifier) { case service::TypeModifier::None: case service::TypeModifier::List: @@ -643,7 +633,7 @@ RequestSchemaType RequestLoader::getSchemaType( } } - switch (*itr) + switch (modifier) { case service::TypeModifier::None: { @@ -911,29 +901,26 @@ void RequestLoader::reorderInputTypeDependencies(Operation& operation) } // Build the dependency list for each input type. - std::for_each(operation.referencedInputTypes.begin(), - operation.referencedInputTypes.end(), - [](RequestInputType& entry) noexcept { - const auto& fields = entry.type->inputFields(); - std::for_each(fields.begin(), - fields.end(), - [&entry](const std::shared_ptr& field) noexcept { - const auto [inputType, modifiers] = unwrapSchemaType(field->type().lock()); - - if (inputType->kind() == introspection::TypeKind::INPUT_OBJECT) + std::ranges::for_each(operation.referencedInputTypes, [](RequestInputType& entry) noexcept { + const auto& fields = entry.type->inputFields(); + std::ranges::for_each(fields, + [&entry](const std::shared_ptr& field) noexcept { + const auto [inputType, modifiers] = unwrapSchemaType(field->type().lock()); + + if (inputType->kind() == introspection::TypeKind::INPUT_OBJECT) + { + // https://spec.graphql.org/October2021/#sec-Input-Objects.Circular-References + if (!modifiers.empty() && modifiers.front() != service::TypeModifier::None) { - // https://spec.graphql.org/October2021/#sec-Input-Objects.Circular-References - if (!modifiers.empty() && modifiers.front() != service::TypeModifier::None) - { - entry.declarations.push_back(inputType->name()); - } - else - { - entry.dependencies.insert(inputType->name()); - } + entry.declarations.push_back(inputType->name()); } - }); - }); + else + { + entry.dependencies.insert(inputType->name()); + } + } + }); + }); std::unordered_set handled; auto itr = operation.referencedInputTypes.begin(); diff --git a/src/Schema.cpp b/src/Schema.cpp index 2e4ac1ba..b448089a 100644 --- a/src/Schema.cpp +++ b/src/Schema.cpp @@ -371,12 +371,9 @@ EnumType::EnumType(init&& params) void EnumType::AddEnumValues(std::vector&& enumValues) { _enumValues.resize(enumValues.size()); - std::transform(enumValues.begin(), - enumValues.end(), - _enumValues.begin(), - [](const auto& value) { - return EnumValue::Make(value.value, value.description, value.deprecationReason); - }); + std::ranges::transform(enumValues, _enumValues.begin(), [](const auto& value) { + return EnumValue::Make(value.value, value.description, value.deprecationReason); + }); } std::string_view EnumType::name() const noexcept diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index c6ef33df..d0d26f18 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -243,17 +244,14 @@ static_assert(graphql::internal::MinorVersion == )cpp" std::vector> sortedValues( enumType.values.size()); - std::transform(enumType.values.cbegin(), - enumType.values.cend(), + std::ranges::transform(enumType.values, sortedValues.begin(), [](const auto& value) noexcept { return std::make_pair(value.value, value.cppValue); }); - std::sort(sortedValues.begin(), - sortedValues.end(), - [](const auto& lhs, const auto& rhs) noexcept { - return internal::shorter_or_less {}(lhs.first, rhs.first); - }); + std::ranges::sort(sortedValues, [](const auto& lhs, const auto& rhs) noexcept { + return internal::shorter_or_less {}(lhs.first, rhs.first); + }); firstValue = true; @@ -2518,8 +2516,7 @@ service::ResolverMap )cpp" std::map resolvers; - std::transform(objectType.fields.cbegin(), - objectType.fields.cend(), + std::ranges::transform(objectType.fields, std::inserter(resolvers, resolvers.begin()), [](const OutputField& outputField) noexcept { const auto resolverName = SchemaLoader::getOutputCppResolver(outputField); diff --git a/src/SchemaLoader.cpp b/src/SchemaLoader.cpp index 3e0827a8..e6c4be43 100644 --- a/src/SchemaLoader.cpp +++ b/src/SchemaLoader.cpp @@ -379,24 +379,22 @@ void SchemaLoader::fixupInputFieldList(InputFieldList& fields) void SchemaLoader::reorderInputTypeDependencies() { // Build the dependency list for each input type. - std::for_each(_inputTypes.begin(), _inputTypes.end(), [](InputType& entry) noexcept { - std::for_each(entry.fields.cbegin(), - entry.fields.cend(), - [&entry](const InputField& field) noexcept { - if (field.fieldType == InputFieldType::Input) + std::ranges::for_each(_inputTypes, [](InputType& entry) noexcept { + std::ranges::for_each(entry.fields, [&entry](const InputField& field) noexcept { + if (field.fieldType == InputFieldType::Input) + { + // https://spec.graphql.org/October2021/#sec-Input-Objects.Circular-References + if (!field.modifiers.empty() + && field.modifiers.front() != service::TypeModifier::None) { - // https://spec.graphql.org/October2021/#sec-Input-Objects.Circular-References - if (!field.modifiers.empty() - && field.modifiers.front() != service::TypeModifier::None) - { - entry.declarations.push_back(field.type); - } - else - { - entry.dependencies.insert(field.type); - } + entry.declarations.push_back(field.type); } - }); + else + { + entry.dependencies.insert(field.type); + } + } + }); }); std::unordered_set handled; diff --git a/src/Validation.cpp b/src/Validation.cpp index 9ed417e1..65204d9e 100644 --- a/src/Validation.cpp +++ b/src/Validation.cpp @@ -575,8 +575,7 @@ void ValidateExecutableVisitor::visit(const peg::ast_node& root) unreferencedFragments.erase(name); } - std::transform(unreferencedFragments.begin(), - unreferencedFragments.end(), + std::ranges::transform(unreferencedFragments, std::back_inserter(_errors), [](const auto& fragmentDefinition) noexcept { auto position = fragmentDefinition.second.get().begin(); diff --git a/test/ResponseTests.cpp b/test/ResponseTests.cpp index 4327186f..9da7d6a0 100644 --- a/test/ResponseTests.cpp +++ b/test/ResponseTests.cpp @@ -5,6 +5,8 @@ #include "graphqlservice/GraphQLResponse.h" +#include + using namespace graphql; TEST(ResponseCase, ValueConstructorFromStringLiteral) @@ -22,7 +24,7 @@ TEST(ResponseCase, IdTypeCompareEqual) std::string_view fakeIdString { "fakeId" }; response::IdType result(fakeIdString.size()); - std::copy(fakeIdString.cbegin(), fakeIdString.cend(), result.begin()); + std::ranges::copy(fakeIdString, result.begin()); return response::IdType { std::move(result) }; }(); From e8d8a856a9128cbf2dd4f7f407b0e97464006773 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 16 Sep 2024 17:55:48 -0700 Subject: [PATCH 068/123] feat(format): replace trivial uses of std::ostringstream with std::format --- include/graphqlservice/GraphQLService.h | 24 +- samples/client/benchmark/BenchmarkClient.cpp | 1 - .../client/multiple/MultipleQueriesClient.cpp | 1 - samples/client/mutate/MutateClient.cpp | 1 - .../client/nestedinput/NestedInputClient.cpp | 1 - samples/client/query/QueryClient.cpp | 1 - samples/client/subscribe/SubscribeClient.cpp | 1 - samples/learn/schema/DroidObject.cpp | 1 - samples/learn/schema/HumanObject.cpp | 1 - samples/learn/schema/MutationObject.cpp | 1 - samples/learn/schema/QueryObject.cpp | 1 - samples/learn/schema/ReviewObject.cpp | 1 - samples/learn/schema/StarWarsSchema.cpp | 1 - samples/proxy/query/ProxyClient.cpp | 1 - samples/proxy/schema/ProxySchema.cpp | 1 - samples/proxy/schema/QueryObject.cpp | 1 - samples/today/TodayMock.cpp | 13 +- .../AppointmentConnectionObject.cpp | 1 - .../nointrospection/AppointmentEdgeObject.cpp | 1 - .../nointrospection/AppointmentObject.cpp | 1 - .../CompleteTaskPayloadObject.cpp | 1 - .../today/nointrospection/ExpensiveObject.cpp | 1 - .../FolderConnectionObject.cpp | 1 - .../nointrospection/FolderEdgeObject.cpp | 1 - .../today/nointrospection/FolderObject.cpp | 1 - .../today/nointrospection/MutationObject.cpp | 1 - .../nointrospection/NestedTypeObject.cpp | 1 - .../today/nointrospection/PageInfoObject.cpp | 1 - samples/today/nointrospection/QueryObject.cpp | 1 - .../nointrospection/SubscriptionObject.cpp | 1 - .../nointrospection/TaskConnectionObject.cpp | 1 - .../today/nointrospection/TaskEdgeObject.cpp | 1 - samples/today/nointrospection/TaskObject.cpp | 1 - samples/today/nointrospection/TodaySchema.cpp | 1 - .../schema/AppointmentConnectionObject.cpp | 1 - .../today/schema/AppointmentEdgeObject.cpp | 1 - samples/today/schema/AppointmentObject.cpp | 1 - .../schema/CompleteTaskPayloadObject.cpp | 1 - samples/today/schema/ExpensiveObject.cpp | 1 - .../today/schema/FolderConnectionObject.cpp | 1 - samples/today/schema/FolderEdgeObject.cpp | 1 - samples/today/schema/FolderObject.cpp | 1 - samples/today/schema/MutationObject.cpp | 1 - samples/today/schema/NestedTypeObject.cpp | 1 - samples/today/schema/PageInfoObject.cpp | 1 - samples/today/schema/QueryObject.cpp | 1 - samples/today/schema/SubscriptionObject.cpp | 1 - samples/today/schema/TaskConnectionObject.cpp | 1 - samples/today/schema/TaskEdgeObject.cpp | 1 - samples/today/schema/TaskObject.cpp | 1 - samples/today/schema/TodaySchema.cpp | 1 - samples/validation/schema/AlienObject.cpp | 1 - samples/validation/schema/ArgumentsObject.cpp | 1 - samples/validation/schema/CatObject.cpp | 1 - samples/validation/schema/DogObject.cpp | 1 - samples/validation/schema/HumanObject.cpp | 1 - samples/validation/schema/MessageObject.cpp | 1 - .../schema/MutateDogResultObject.cpp | 1 - samples/validation/schema/MutationObject.cpp | 1 - samples/validation/schema/QueryObject.cpp | 1 - .../validation/schema/SubscriptionObject.cpp | 1 - .../validation/schema/ValidationSchema.cpp | 1 - src/ClientGenerator.cpp | 36 +- src/GeneratorLoader.cpp | 10 +- src/GraphQLService.cpp | 124 ++--- src/RequestLoader.cpp | 35 +- src/SchemaGenerator.cpp | 60 +-- src/SchemaLoader.cpp | 161 +++--- src/SyntaxTree.cpp | 13 +- src/Validation.cpp | 457 ++++++++---------- src/introspection/DirectiveObject.cpp | 1 - src/introspection/EnumValueObject.cpp | 1 - src/introspection/FieldObject.cpp | 1 - src/introspection/InputValueObject.cpp | 1 - src/introspection/IntrospectionSchema.cpp | 1 - src/introspection/SchemaObject.cpp | 1 - src/introspection/TypeObject.cpp | 1 - 77 files changed, 388 insertions(+), 612 deletions(-) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index b6c84687..1474e91a 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -686,11 +686,7 @@ struct ModifiedArgument for (auto& error : errors) { - std::ostringstream message; - - message << "Invalid argument: " << name << " error: " << error.message; - - error.message = message.str(); + error.message = std::format("Invalid argument: {} error: {}", name, error.message); } throw schema_exception(std::move(errors)); @@ -1201,12 +1197,11 @@ struct ModifiedResult } catch (const std::exception& ex) { - std::ostringstream message; + auto message = std::format("Field error name: {} unknown error: {}", + params.fieldName, + ex.what()); - message << "Field error name: " << params.fieldName - << " unknown error: " << ex.what(); - - document.errors.emplace_back(schema_error { message.str(), + document.errors.emplace_back(schema_error { std::move(message), params.getLocation(), buildErrorPath(params.errorPath) }); } @@ -1294,11 +1289,10 @@ struct ModifiedResult } catch (const std::exception& ex) { - std::ostringstream message; - - message << "Field name: " << params.fieldName << " unknown error: " << ex.what(); + auto message = + std::format("Field name: {} unknown error: {}", params.fieldName, ex.what()); - document.errors.emplace_back(schema_error { message.str(), + document.errors.emplace_back(schema_error { std::move(message), params.getLocation(), buildErrorPath(params.errorPath) }); } diff --git a/samples/client/benchmark/BenchmarkClient.cpp b/samples/client/benchmark/BenchmarkClient.cpp index 4ce3e7d6..5a7e346b 100644 --- a/samples/client/benchmark/BenchmarkClient.cpp +++ b/samples/client/benchmark/BenchmarkClient.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/client/multiple/MultipleQueriesClient.cpp b/samples/client/multiple/MultipleQueriesClient.cpp index 5383da2f..3b5d533f 100644 --- a/samples/client/multiple/MultipleQueriesClient.cpp +++ b/samples/client/multiple/MultipleQueriesClient.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/client/mutate/MutateClient.cpp b/samples/client/mutate/MutateClient.cpp index 019f2f43..8db8bd6a 100644 --- a/samples/client/mutate/MutateClient.cpp +++ b/samples/client/mutate/MutateClient.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/client/nestedinput/NestedInputClient.cpp b/samples/client/nestedinput/NestedInputClient.cpp index 16708663..8de48529 100644 --- a/samples/client/nestedinput/NestedInputClient.cpp +++ b/samples/client/nestedinput/NestedInputClient.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/client/query/QueryClient.cpp b/samples/client/query/QueryClient.cpp index 61422c40..0e874d20 100644 --- a/samples/client/query/QueryClient.cpp +++ b/samples/client/query/QueryClient.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/client/subscribe/SubscribeClient.cpp b/samples/client/subscribe/SubscribeClient.cpp index cf76839b..ea516d6c 100644 --- a/samples/client/subscribe/SubscribeClient.cpp +++ b/samples/client/subscribe/SubscribeClient.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/learn/schema/DroidObject.cpp b/samples/learn/schema/DroidObject.cpp index 6f9a706f..16473f96 100644 --- a/samples/learn/schema/DroidObject.cpp +++ b/samples/learn/schema/DroidObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/learn/schema/HumanObject.cpp b/samples/learn/schema/HumanObject.cpp index 1094ed45..ab8ad2ed 100644 --- a/samples/learn/schema/HumanObject.cpp +++ b/samples/learn/schema/HumanObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/learn/schema/MutationObject.cpp b/samples/learn/schema/MutationObject.cpp index 9bdb2b5f..ef6dcbb1 100644 --- a/samples/learn/schema/MutationObject.cpp +++ b/samples/learn/schema/MutationObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/learn/schema/QueryObject.cpp b/samples/learn/schema/QueryObject.cpp index bc1cf10f..061d89aa 100644 --- a/samples/learn/schema/QueryObject.cpp +++ b/samples/learn/schema/QueryObject.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include diff --git a/samples/learn/schema/ReviewObject.cpp b/samples/learn/schema/ReviewObject.cpp index ebe1c4b9..240ed953 100644 --- a/samples/learn/schema/ReviewObject.cpp +++ b/samples/learn/schema/ReviewObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/learn/schema/StarWarsSchema.cpp b/samples/learn/schema/StarWarsSchema.cpp index a5d8e9e2..5288f5d8 100644 --- a/samples/learn/schema/StarWarsSchema.cpp +++ b/samples/learn/schema/StarWarsSchema.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/proxy/query/ProxyClient.cpp b/samples/proxy/query/ProxyClient.cpp index 04b6546c..6124a0ac 100644 --- a/samples/proxy/query/ProxyClient.cpp +++ b/samples/proxy/query/ProxyClient.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/proxy/schema/ProxySchema.cpp b/samples/proxy/schema/ProxySchema.cpp index e38783ba..0a6dc2f9 100644 --- a/samples/proxy/schema/ProxySchema.cpp +++ b/samples/proxy/schema/ProxySchema.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/proxy/schema/QueryObject.cpp b/samples/proxy/schema/QueryObject.cpp index f8989a70..b07fe96c 100644 --- a/samples/proxy/schema/QueryObject.cpp +++ b/samples/proxy/schema/QueryObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index d7464511..4d808469 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -569,10 +570,8 @@ struct EdgeConstraints { if (*first < 0) { - std::ostringstream error; - - error << "Invalid argument: first value: " << *first; - throw service::schema_exception { { service::schema_error { error.str() } } }; + auto error = std::format("Invalid argument: first value: {}", *first); + throw service::schema_exception { { service::schema_error { std::move(error) } } }; } if (itrLast - itrFirst > *first) @@ -585,10 +584,8 @@ struct EdgeConstraints { if (*last < 0) { - std::ostringstream error; - - error << "Invalid argument: last value: " << *last; - throw service::schema_exception { { service::schema_error { error.str() } } }; + auto error = std::format("Invalid argument: last value: {}", *last); + throw service::schema_exception { { service::schema_error { std::move(error) } } }; } if (itrLast - itrFirst > *last) diff --git a/samples/today/nointrospection/AppointmentConnectionObject.cpp b/samples/today/nointrospection/AppointmentConnectionObject.cpp index d0fe0178..9ea706b8 100644 --- a/samples/today/nointrospection/AppointmentConnectionObject.cpp +++ b/samples/today/nointrospection/AppointmentConnectionObject.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/AppointmentEdgeObject.cpp b/samples/today/nointrospection/AppointmentEdgeObject.cpp index f599fdf2..b79f8a66 100644 --- a/samples/today/nointrospection/AppointmentEdgeObject.cpp +++ b/samples/today/nointrospection/AppointmentEdgeObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/AppointmentObject.cpp b/samples/today/nointrospection/AppointmentObject.cpp index 63062308..4ff77df9 100644 --- a/samples/today/nointrospection/AppointmentObject.cpp +++ b/samples/today/nointrospection/AppointmentObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/CompleteTaskPayloadObject.cpp b/samples/today/nointrospection/CompleteTaskPayloadObject.cpp index 0e0e08b0..584a011d 100644 --- a/samples/today/nointrospection/CompleteTaskPayloadObject.cpp +++ b/samples/today/nointrospection/CompleteTaskPayloadObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/ExpensiveObject.cpp b/samples/today/nointrospection/ExpensiveObject.cpp index 4583f271..6c984f82 100644 --- a/samples/today/nointrospection/ExpensiveObject.cpp +++ b/samples/today/nointrospection/ExpensiveObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/FolderConnectionObject.cpp b/samples/today/nointrospection/FolderConnectionObject.cpp index 75a588a3..78fd9094 100644 --- a/samples/today/nointrospection/FolderConnectionObject.cpp +++ b/samples/today/nointrospection/FolderConnectionObject.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/FolderEdgeObject.cpp b/samples/today/nointrospection/FolderEdgeObject.cpp index 203c1aa2..179e4c37 100644 --- a/samples/today/nointrospection/FolderEdgeObject.cpp +++ b/samples/today/nointrospection/FolderEdgeObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/FolderObject.cpp b/samples/today/nointrospection/FolderObject.cpp index 9f0b44e5..2fc07efd 100644 --- a/samples/today/nointrospection/FolderObject.cpp +++ b/samples/today/nointrospection/FolderObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/MutationObject.cpp b/samples/today/nointrospection/MutationObject.cpp index 4482e672..dd7228d1 100644 --- a/samples/today/nointrospection/MutationObject.cpp +++ b/samples/today/nointrospection/MutationObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/NestedTypeObject.cpp b/samples/today/nointrospection/NestedTypeObject.cpp index 0298ed0a..f85ca02c 100644 --- a/samples/today/nointrospection/NestedTypeObject.cpp +++ b/samples/today/nointrospection/NestedTypeObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/PageInfoObject.cpp b/samples/today/nointrospection/PageInfoObject.cpp index c356dbac..15021499 100644 --- a/samples/today/nointrospection/PageInfoObject.cpp +++ b/samples/today/nointrospection/PageInfoObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/QueryObject.cpp b/samples/today/nointrospection/QueryObject.cpp index e624f909..f87d63d6 100644 --- a/samples/today/nointrospection/QueryObject.cpp +++ b/samples/today/nointrospection/QueryObject.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/SubscriptionObject.cpp b/samples/today/nointrospection/SubscriptionObject.cpp index 104e9fe0..16a729fc 100644 --- a/samples/today/nointrospection/SubscriptionObject.cpp +++ b/samples/today/nointrospection/SubscriptionObject.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/TaskConnectionObject.cpp b/samples/today/nointrospection/TaskConnectionObject.cpp index a49a51ac..0950ae4c 100644 --- a/samples/today/nointrospection/TaskConnectionObject.cpp +++ b/samples/today/nointrospection/TaskConnectionObject.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/TaskEdgeObject.cpp b/samples/today/nointrospection/TaskEdgeObject.cpp index 300a0737..d48b9bad 100644 --- a/samples/today/nointrospection/TaskEdgeObject.cpp +++ b/samples/today/nointrospection/TaskEdgeObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/TaskObject.cpp b/samples/today/nointrospection/TaskObject.cpp index cd58aa7a..8ce3d664 100644 --- a/samples/today/nointrospection/TaskObject.cpp +++ b/samples/today/nointrospection/TaskObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/today/nointrospection/TodaySchema.cpp b/samples/today/nointrospection/TodaySchema.cpp index 4dd8886a..cb72d659 100644 --- a/samples/today/nointrospection/TodaySchema.cpp +++ b/samples/today/nointrospection/TodaySchema.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/today/schema/AppointmentConnectionObject.cpp b/samples/today/schema/AppointmentConnectionObject.cpp index d0fe0178..9ea706b8 100644 --- a/samples/today/schema/AppointmentConnectionObject.cpp +++ b/samples/today/schema/AppointmentConnectionObject.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/AppointmentEdgeObject.cpp b/samples/today/schema/AppointmentEdgeObject.cpp index f599fdf2..b79f8a66 100644 --- a/samples/today/schema/AppointmentEdgeObject.cpp +++ b/samples/today/schema/AppointmentEdgeObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/AppointmentObject.cpp b/samples/today/schema/AppointmentObject.cpp index 63062308..4ff77df9 100644 --- a/samples/today/schema/AppointmentObject.cpp +++ b/samples/today/schema/AppointmentObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/CompleteTaskPayloadObject.cpp b/samples/today/schema/CompleteTaskPayloadObject.cpp index 0e0e08b0..584a011d 100644 --- a/samples/today/schema/CompleteTaskPayloadObject.cpp +++ b/samples/today/schema/CompleteTaskPayloadObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/ExpensiveObject.cpp b/samples/today/schema/ExpensiveObject.cpp index 4583f271..6c984f82 100644 --- a/samples/today/schema/ExpensiveObject.cpp +++ b/samples/today/schema/ExpensiveObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/FolderConnectionObject.cpp b/samples/today/schema/FolderConnectionObject.cpp index 75a588a3..78fd9094 100644 --- a/samples/today/schema/FolderConnectionObject.cpp +++ b/samples/today/schema/FolderConnectionObject.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/FolderEdgeObject.cpp b/samples/today/schema/FolderEdgeObject.cpp index 203c1aa2..179e4c37 100644 --- a/samples/today/schema/FolderEdgeObject.cpp +++ b/samples/today/schema/FolderEdgeObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/FolderObject.cpp b/samples/today/schema/FolderObject.cpp index 9f0b44e5..2fc07efd 100644 --- a/samples/today/schema/FolderObject.cpp +++ b/samples/today/schema/FolderObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/MutationObject.cpp b/samples/today/schema/MutationObject.cpp index 4482e672..dd7228d1 100644 --- a/samples/today/schema/MutationObject.cpp +++ b/samples/today/schema/MutationObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/NestedTypeObject.cpp b/samples/today/schema/NestedTypeObject.cpp index bd9c90d1..fc772276 100644 --- a/samples/today/schema/NestedTypeObject.cpp +++ b/samples/today/schema/NestedTypeObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/PageInfoObject.cpp b/samples/today/schema/PageInfoObject.cpp index c356dbac..15021499 100644 --- a/samples/today/schema/PageInfoObject.cpp +++ b/samples/today/schema/PageInfoObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/QueryObject.cpp b/samples/today/schema/QueryObject.cpp index ac999274..953af738 100644 --- a/samples/today/schema/QueryObject.cpp +++ b/samples/today/schema/QueryObject.cpp @@ -22,7 +22,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/SubscriptionObject.cpp b/samples/today/schema/SubscriptionObject.cpp index 104e9fe0..16a729fc 100644 --- a/samples/today/schema/SubscriptionObject.cpp +++ b/samples/today/schema/SubscriptionObject.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/TaskConnectionObject.cpp b/samples/today/schema/TaskConnectionObject.cpp index a49a51ac..0950ae4c 100644 --- a/samples/today/schema/TaskConnectionObject.cpp +++ b/samples/today/schema/TaskConnectionObject.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/TaskEdgeObject.cpp b/samples/today/schema/TaskEdgeObject.cpp index 300a0737..d48b9bad 100644 --- a/samples/today/schema/TaskEdgeObject.cpp +++ b/samples/today/schema/TaskEdgeObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/TaskObject.cpp b/samples/today/schema/TaskObject.cpp index cd58aa7a..8ce3d664 100644 --- a/samples/today/schema/TaskObject.cpp +++ b/samples/today/schema/TaskObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/today/schema/TodaySchema.cpp b/samples/today/schema/TodaySchema.cpp index 27cd44ce..f55a0831 100644 --- a/samples/today/schema/TodaySchema.cpp +++ b/samples/today/schema/TodaySchema.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/validation/schema/AlienObject.cpp b/samples/validation/schema/AlienObject.cpp index 0687dff9..b6c0d4be 100644 --- a/samples/validation/schema/AlienObject.cpp +++ b/samples/validation/schema/AlienObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/validation/schema/ArgumentsObject.cpp b/samples/validation/schema/ArgumentsObject.cpp index 80a06987..0a180be7 100644 --- a/samples/validation/schema/ArgumentsObject.cpp +++ b/samples/validation/schema/ArgumentsObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/validation/schema/CatObject.cpp b/samples/validation/schema/CatObject.cpp index 35dcb20a..30df47f5 100644 --- a/samples/validation/schema/CatObject.cpp +++ b/samples/validation/schema/CatObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/validation/schema/DogObject.cpp b/samples/validation/schema/DogObject.cpp index e6785b43..6e5aeb7b 100644 --- a/samples/validation/schema/DogObject.cpp +++ b/samples/validation/schema/DogObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/validation/schema/HumanObject.cpp b/samples/validation/schema/HumanObject.cpp index 7294ffd2..6b0450a1 100644 --- a/samples/validation/schema/HumanObject.cpp +++ b/samples/validation/schema/HumanObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/validation/schema/MessageObject.cpp b/samples/validation/schema/MessageObject.cpp index 5897962e..df48b7f7 100644 --- a/samples/validation/schema/MessageObject.cpp +++ b/samples/validation/schema/MessageObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/validation/schema/MutateDogResultObject.cpp b/samples/validation/schema/MutateDogResultObject.cpp index 7ca813a2..ab872c93 100644 --- a/samples/validation/schema/MutateDogResultObject.cpp +++ b/samples/validation/schema/MutateDogResultObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/samples/validation/schema/MutationObject.cpp b/samples/validation/schema/MutationObject.cpp index 1ec98fb1..6a1fc565 100644 --- a/samples/validation/schema/MutationObject.cpp +++ b/samples/validation/schema/MutationObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/validation/schema/QueryObject.cpp b/samples/validation/schema/QueryObject.cpp index 2bf27de3..c15a5f0b 100644 --- a/samples/validation/schema/QueryObject.cpp +++ b/samples/validation/schema/QueryObject.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/samples/validation/schema/SubscriptionObject.cpp b/samples/validation/schema/SubscriptionObject.cpp index 694693b8..e0437189 100644 --- a/samples/validation/schema/SubscriptionObject.cpp +++ b/samples/validation/schema/SubscriptionObject.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/samples/validation/schema/ValidationSchema.cpp b/samples/validation/schema/ValidationSchema.cpp index 40410c97..bc7c42b8 100644 --- a/samples/validation/schema/ValidationSchema.cpp +++ b/samples/validation/schema/ValidationSchema.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 5b472775..8af33dff 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -113,12 +114,11 @@ const std::string& Generator::getOperationNamespace(const Operation& operation) for (const auto& entry : operations) { - std::ostringstream oss; + auto value = std::format(R"cpp({}::{})cpp", + _requestLoader.getOperationType(entry), + _requestLoader.getOperationNamespace(entry)); - oss << _requestLoader.getOperationType(entry) << R"cpp(::)cpp" - << _requestLoader.getOperationNamespace(entry); - - result.emplace(entry.name, oss.str()); + result.emplace(entry.name, std::move(value)); } return result; @@ -138,15 +138,17 @@ std::string Generator::getResponseFieldCppType( case introspection::TypeKind::INTERFACE: case introspection::TypeKind::UNION: { - std::ostringstream oss; + std::string prefix; if (!currentScope.empty()) { - oss << currentScope << R"cpp(::)cpp"; + prefix = std::format(R"cpp({}::)cpp", currentScope); } - oss << responseField.cppName << R"cpp(_)cpp" << responseField.type->name(); - result = SchemaLoader::getSafeCppName(oss.str()); + result = SchemaLoader::getSafeCppName(std::format(R"cpp({}{}_{})cpp", + prefix, + responseField.cppName, + responseField.type->name())); break; } @@ -619,7 +621,6 @@ bool Generator::outputResponseFieldType(std::ostream& headerFile, bool Generator::outputModule() const noexcept { std::ofstream moduleFile(_modulePath, std::ios_base::trunc); - std::ostringstream ossNamespace; moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. @@ -810,7 +811,6 @@ bool Generator::outputSource() const noexcept #include #include #include -#include #include #include #include @@ -1167,11 +1167,8 @@ response::Value Variable<)cpp" pendingSeparator.add(); } - std::ostringstream oss; - - oss << getOperationNamespace(operation) << R"cpp(::Response)cpp"; - - const auto currentScope = oss.str(); + const auto currentScope = + std::format(R"cpp({}::Response)cpp", getOperationNamespace(operation)); const auto& responseType = _requestLoader.getResponseType(operation); for (const auto& responseField : responseType.fields) @@ -1350,11 +1347,8 @@ const std::string& GetOperationName() noexcept bool Generator::outputModifiedResponseImplementation(std::ostream& sourceFile, const std::string& outerScope, const ResponseField& responseField) const noexcept { - std::ostringstream oss; - - oss << outerScope << R"cpp(::)cpp" << getResponseFieldCppType(responseField); - - const auto cppType = oss.str(); + const auto cppType = + std::format(R"cpp({}::{})cpp", outerScope, getResponseFieldCppType(responseField)); std::unordered_set fieldNames; switch (responseField.type->kind()) diff --git a/src/GeneratorLoader.cpp b/src/GeneratorLoader.cpp index c57ed8fe..38c3c29a 100644 --- a/src/GeneratorLoader.cpp +++ b/src/GeneratorLoader.cpp @@ -6,6 +6,7 @@ #include "graphqlservice/internal/Grammar.h" #include +#include namespace graphql::generator { @@ -96,13 +97,12 @@ void DefaultValueVisitor::visit(const peg::ast_node& value) } else if (value.is_type()) { - std::ostringstream error; const auto position = value.begin(); + const auto error = std::format("Unexpected variable in default value line: {} column: {}", + position.line, + position.column); - error << "Unexpected variable in default value line: " << position.line - << " column: " << position.column; - - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } } diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index 39b74479..ab84142a 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -170,13 +170,7 @@ unimplemented_method::unimplemented_method(std::string_view methodName) std::string unimplemented_method::getMessage(std::string_view methodName) noexcept { - using namespace std::literals; - - std::ostringstream oss; - - oss << methodName << R"ex( is not implemented)ex"sv; - - return oss.str(); + return std::format(R"ex({} is not implemented)ex", methodName); } void await_worker_thread::await_suspend(std::coroutine_handle<> h) const @@ -371,12 +365,10 @@ void ValueVisitor::visitVariable(const peg::ast_node& variable) if (itr == _variables.get().cend()) { auto position = variable.begin(); - std::ostringstream error; - - error << "Unknown variable name: " << name; + auto error = std::format("Unknown variable name: {}", name); throw schema_exception { - { schema_error { error.str(), { position.line, position.column } } } + { schema_error { std::move(error), { position.line, position.column } } } }; } @@ -535,11 +527,9 @@ bool DirectiveVisitor::shouldSkip() const if (arguments.type() != response::Type::Map) { - std::ostringstream error; - - error << "Invalid arguments to directive: " << directiveName; + auto error = std::format("Invalid arguments to directive: {}", directiveName); - throw schema_exception { { error.str() } }; + throw schema_exception { { std::move(error) } }; } bool argumentTrue = false; @@ -550,12 +540,11 @@ bool DirectiveVisitor::shouldSkip() const if (argumentTrue || argumentFalse || argumentValue.type() != response::Type::Boolean || argumentName != "if") { - std::ostringstream error; - - error << "Invalid argument to directive: " << directiveName - << " name: " << argumentName; + auto error = std::format("Invalid argument to directive: {} name: {}", + directiveName, + argumentName); - throw schema_exception { { error.str() } }; + throw schema_exception { { std::move(error) } }; } argumentTrue = argumentValue.get(); @@ -572,11 +561,9 @@ bool DirectiveVisitor::shouldSkip() const } else { - std::ostringstream error; + auto error = std::format("Missing argument directive: {} name: if", directiveName); - error << "Missing argument directive: " << directiveName << " name: if"; - - throw schema_exception { { error.str() } }; + throw schema_exception { { std::move(error) } }; } } @@ -700,11 +687,9 @@ void blockSubFields(const ResolverParams& params) if (params.selection != nullptr) { auto position = params.selection->begin(); - std::ostringstream error; - - error << "Field may not have sub-fields name: " << params.fieldName; + auto error = std::format("Field may not have sub-fields name: {}", params.fieldName); - throw schema_exception { { schema_error { error.str(), + throw schema_exception { { schema_error { std::move(error), { position.line, position.column }, buildErrorPath(params.errorPath) } } }; } @@ -791,11 +776,9 @@ void requireSubFields(const ResolverParams& params) if (params.selection == nullptr) { auto position = params.field.begin(); - std::ostringstream error; - - error << "Field must have sub-fields name: " << params.fieldName; + auto error = std::format("Field must have sub-fields name: {}", params.fieldName); - throw schema_exception { { schema_error { error.str(), + throw schema_exception { { schema_error { std::move(error), { position.line, position.column }, buildErrorPath(params.errorPath) } } }; } @@ -1007,12 +990,10 @@ void SelectionVisitor::visitField(const peg::ast_node& field) { std::promise promise; auto position = field.begin(); - std::ostringstream error; - - error << "Unknown field name: " << name; + auto error = std::format("Unknown field name: {}", name); promise.set_exception( - std::make_exception_ptr(schema_exception { { schema_error { error.str(), + std::make_exception_ptr(schema_exception { { schema_error { std::move(error), { position.line, position.column }, buildErrorPath(_path ? std::make_optional(_path->get()) : std::nullopt) } } })); @@ -1101,12 +1082,10 @@ void SelectionVisitor::visitField(const peg::ast_node& field) catch (const std::exception& ex) { std::promise promise; - std::ostringstream message; - - message << "Field error name: " << alias << " unknown error: " << ex.what(); + auto message = std::format("Field error name: {} unknown error: ", alias, ex.what()); promise.set_exception( - std::make_exception_ptr(schema_exception { { schema_error { message.str(), + std::make_exception_ptr(schema_exception { { schema_error { std::move(message), { position.line, position.column }, buildErrorPath(selectionSetParams.errorPath) } } })); @@ -1122,11 +1101,9 @@ void SelectionVisitor::visitFragmentSpread(const peg::ast_node& fragmentSpread) if (itr == _fragments.end()) { auto position = fragmentSpread.begin(); - std::ostringstream error; + auto error = std::format("Unknown fragment name: {}", name); - error << "Unknown fragment name: " << name; - - throw schema_exception { { schema_error { error.str(), + throw schema_exception { { schema_error { std::move(error), { position.line, position.column }, buildErrorPath(_path ? std::make_optional(_path->get()) : std::nullopt) } } }; } @@ -1261,13 +1238,10 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, if (!document.data.emplace_back(std::string { child.name }, std::move(value.data))) { - std::ostringstream message; - - message << "Ambiguous field error name: " << child.name; - + auto message = std::format("Ambiguous field error name: {}", child.name); field_path path { parent, path_segment { child.name } }; - document.errors.push_back({ message.str(), + document.errors.push_back({ std::move(message), child.location.value_or(schema_location {}), buildErrorPath(std::make_optional(path)) }); } @@ -1290,13 +1264,11 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, } catch (const std::exception& ex) { - std::ostringstream message; - - message << "Field error name: " << child.name << " unknown error: " << ex.what(); - + auto message = + std::format("Field error name: {} unknown error: {}", child.name, ex.what()); field_path path { parent, path_segment { child.name } }; - document.errors.push_back({ message.str(), + document.errors.push_back({ std::move(message), child.location.value_or(schema_location {}), buildErrorPath(std::make_optional(path)) }); document.data.emplace_back(std::string { child.name }, {}); @@ -1598,12 +1570,10 @@ void SubscriptionDefinitionVisitor::visitField(const peg::ast_node& field) if (!_field.empty()) { auto position = field.begin(); - std::ostringstream error; - - error << "Extra subscription root field name: " << name; + auto error = std::format("Extra subscription root field name: {}", name); throw schema_exception { - { schema_error { error.str(), { position.line, position.column } } } + { schema_error { std::move(error), { position.line, position.column } } } }; } @@ -1645,12 +1615,10 @@ void SubscriptionDefinitionVisitor::visitFragmentSpread(const peg::ast_node& fra if (itr == _fragments.end()) { auto position = fragmentSpread.begin(); - std::ostringstream error; - - error << "Unknown fragment name: " << name; + auto error = std::format("Unknown fragment name: {}", name); throw schema_exception { - { schema_error { error.str(), { position.line, position.column } } } + { schema_error { std::move(error), { position.line, position.column } } } }; } @@ -1798,31 +1766,27 @@ response::AwaitableValue Request::resolve(RequestResolveParams params) const if (!operationDefinition) { - std::ostringstream message; - - message << "Missing operation"; + auto message = "Missing operation"s; if (!params.operationName.empty()) { - message << " name: " << params.operationName; + message += std::format(" name: {}", params.operationName); } - throw schema_exception { { message.str() } }; + throw schema_exception { { std::move(message) } }; } else if (operationType == strSubscription) { auto position = operationDefinition->begin(); - std::ostringstream message; - - message << "Unexpected subscription"; + auto message = "Unexpected subscription"s; if (!params.operationName.empty()) { - message << " name: " << params.operationName; + message += std::format(" name: {}", params.operationName); } throw schema_exception { - { schema_error { message.str(), { position.line, position.column } } } + { schema_error { std::move(message), { position.line, position.column } } } }; } @@ -2076,31 +2040,27 @@ SubscriptionKey Request::addSubscription(RequestSubscribeParams&& params) if (!operationDefinition) { - std::ostringstream message; - - message << "Missing subscription"; + auto message = "Missing subscription"s; if (!params.operationName.empty()) { - message << " name: " << params.operationName; + message += std::format(" name: {}", params.operationName); } - throw schema_exception { { message.str() } }; + throw schema_exception { { std::move(message) } }; } else if (operationType != strSubscription) { auto position = operationDefinition->begin(); - std::ostringstream message; - - message << "Unexpected operation type: " << operationType; + auto message = std::format("Unexpected operation type: {}", operationType); if (!params.operationName.empty()) { - message << " name: " << params.operationName; + message += std::format(" name: {}", params.operationName); } throw schema_exception { - { schema_error { message.str(), { position.line, position.column } } } + { schema_error { std::move(message), { position.line, position.column } } } }; } diff --git a/src/RequestLoader.cpp b/src/RequestLoader.cpp index 2673c707..0e59f661 100644 --- a/src/RequestLoader.cpp +++ b/src/RequestLoader.cpp @@ -733,16 +733,14 @@ void RequestLoader::findOperation() if (_operations.empty()) { - std::ostringstream message; - - message << "Missing operation"; + auto message = "Missing operation"s; if (_requestOptions.operationName && !_requestOptions.operationName->empty()) { - message << " name: " << *_requestOptions.operationName; + message += std::format(" name: {}", *_requestOptions.operationName); } - throw service::schema_exception { { message.str() } }; + throw service::schema_exception { { std::move(message) } }; } std::list errors; @@ -764,17 +762,15 @@ void RequestLoader::findOperation() if (!operation.responseType.type) { - std::ostringstream message; const auto position = operation.operation->begin(); - - message << "Unsupported operation type: " << operation.type; + auto message = std::format("Unsupported operation type: {}", operation.type); if (!operation.name.empty()) { - message << " name: " << operation.name; + message += std::format(" name: {}", operation.name); } - service::schema_error error { message.str(), + service::schema_error error { std::move(message), service::schema_location { position.line, position.column } }; errors.push_back(std::move(error)); @@ -842,12 +838,11 @@ void RequestLoader::collectVariables(Operation& operation) noexcept && variable.defaultValue.type() == response::Type::Null && (modifiers.empty() || modifiers.front() != service::TypeModifier::Nullable)) { - std::ostringstream error; - - error << "Expected Non-Null default value for variable name: " << variable.name; + auto error = std::format("Expected Non-Null default value for variable name: {}", + variable.name); throw service::schema_exception { - { service::schema_error { error.str(), std::move(defaultValueLocation) } } + { service::schema_error { std::move(error), std::move(defaultValueLocation) } } }; } @@ -945,11 +940,9 @@ void RequestLoader::reorderInputTypeDependencies(Operation& operation) // input types which are referenced in the request. if (itrDependent == itr) { - std::ostringstream error; + const auto error = std::format("Input object cycle type: {}", itr->type->name()); - error << "Input object cycle type: " << itr->type; - - throw std::logic_error(error.str()); + throw std::logic_error(error); } if (itrDependent != operation.referencedInputTypes.end()) @@ -1181,12 +1174,10 @@ void RequestLoader::SelectionVisitor::visitFragmentSpread(const peg::ast_node& f if (itr == _fragments.end()) { auto position = fragmentSpread.begin(); - std::ostringstream error; - - error << "Unknown fragment name: " << name; + auto error = std::format("Unknown fragment name: {}", name); throw service::schema_exception { - { service::schema_error { error.str(), { position.line, position.column } } } + { service::schema_error { std::move(error), { position.line, position.column } } } }; } diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index d0d26f18..eda453eb 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -687,11 +688,7 @@ GRAPHQLSERVICE_EXPORT )cpp" << _loader.getSchemaNamespace() bool Generator::outputModule() const noexcept { std::ofstream moduleFile(_modulePath, std::ios_base::trunc); - std::ostringstream ossNamespace; - - ossNamespace << R"cpp(graphql::)cpp" << _loader.getSchemaNamespace(); - - const auto schemaNamespace = ossNamespace.str(); + const auto schemaNamespace = std::format(R"cpp(graphql::{})cpp", _loader.getSchemaNamespace()); moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. @@ -1382,13 +1379,10 @@ void Generator::outputObjectDeclaration( std::string Generator::getFieldDeclaration(const InputField& inputField) const noexcept { - std::ostringstream output; - - output << R"cpp( )cpp" << _loader.getInputCppType(inputField) << R"cpp( )cpp" - << inputField.cppName << R"cpp(; -)cpp"; - - return output.str(); + return std::format(R"cpp( {} {}; +)cpp", + _loader.getInputCppType(inputField), + inputField.cppName); } std::string Generator::getFieldDeclaration(const OutputField& outputField) const noexcept @@ -1425,14 +1419,12 @@ std::string Generator::getFieldDeclaration(const OutputField& outputField) const std::string Generator::getResolverDeclaration(const OutputField& outputField) const noexcept { - std::ostringstream output; const auto resolverName = SchemaLoader::getOutputCppResolver(outputField); - output << R"cpp( [[nodiscard("unnecessary call")]] service::AwaitableResolver )cpp" - << resolverName << R"cpp((service::ResolverParams&& params) const; -)cpp"; - - return output.str(); + return std::format( + R"cpp( [[nodiscard("unnecessary call")]] service::AwaitableResolver {}(service::ResolverParams&& params) const; +)cpp", + resolverName); } bool Generator::outputSource() const noexcept @@ -1484,7 +1476,6 @@ bool Generator::outputSource() const noexcept #include #include #include -#include #include #include #include @@ -2520,13 +2511,12 @@ service::ResolverMap )cpp" std::inserter(resolvers, resolvers.begin()), [](const OutputField& outputField) noexcept { const auto resolverName = SchemaLoader::getOutputCppResolver(outputField); - std::ostringstream output; - - output << R"cpp( { R"gql()cpp" << outputField.name - << R"cpp()gql"sv, [this](service::ResolverParams&& params) { return )cpp" - << resolverName << R"cpp((std::move(params)); } })cpp"; + auto output = std::format( + R"cpp( {{ R"gql({})gql"sv, [this](service::ResolverParams&& params) {{ return {}(std::move(params)); }} }})cpp", + outputField.name, + resolverName); - return std::make_pair(std::string_view { outputField.name }, output.str()); + return std::make_pair(std::string_view { outputField.name }, std::move(output)); }); resolvers["__typename"sv] = @@ -3229,16 +3219,8 @@ std::vector Generator::outputSeparateFiles() const noexcept } } - std::ostringstream ossNamespace; - - ossNamespace << R"cpp(graphql::)cpp" << _loader.getSchemaNamespace(); - - const auto schemaNamespace = ossNamespace.str(); - std::ostringstream ossInterfaceNamespace; - - ossInterfaceNamespace << schemaNamespace << R"cpp(::object)cpp"; - - const auto objectNamespace = ossInterfaceNamespace.str(); + const auto schemaNamespace = std::format(R"cpp(graphql::{})cpp", _loader.getSchemaNamespace()); + const auto objectNamespace = std::format(R"cpp({}::object)cpp", schemaNamespace); for (const auto& interfaceType : _loader.getInterfaceTypes()) { @@ -3439,11 +3421,8 @@ using namespace std::literals; } // Output the stub concepts - std::ostringstream ossConceptNamespace; - - ossConceptNamespace << R"cpp(methods::)cpp" << objectType.cppType << R"cpp(Has)cpp"; - - const auto conceptNamespace = ossConceptNamespace.str(); + const auto conceptNamespace = + std::format(R"cpp(methods::{}Has)cpp", objectType.cppType); NamespaceScope stubNamespace { headerFile, conceptNamespace }; outputObjectStubs(headerFile, objectType); @@ -3534,7 +3513,6 @@ using namespace std::literals; sourceFile << R"cpp( #include #include -#include #include #include diff --git a/src/SchemaLoader.cpp b/src/SchemaLoader.cpp index e6c4be43..85bbaa63 100644 --- a/src/SchemaLoader.cpp +++ b/src/SchemaLoader.cpp @@ -78,18 +78,17 @@ void SchemaLoader::validateSchema() { if (s_builtinTypes.find(entry.first) != s_builtinTypes.cend()) { - std::ostringstream error; auto itrPosition = _typePositions.find(entry.first); - - error << "Builtin type overridden: " << entry.first; + auto error = std::format("Builtin type overridden: {}", entry.first); if (itrPosition != _typePositions.cend()) { - error << " line: " << itrPosition->second.line - << " column: " << itrPosition->second.column; + error += std::format(" line: {} column: {}", + itrPosition->second.line, + itrPosition->second.column); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } } @@ -149,12 +148,11 @@ void SchemaLoader::validateSchema() { if (_objectNames.find(operation.type) == _objectNames.cend()) { - std::ostringstream error; - - error << "Unknown operation type: " << operation.type - << " operation: " << operation.operation; + const auto error = std::format("Unknown operation type: {} operation: {}", + operation.type, + operation.operation); - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } queryDefined = queryDefined || (operation.operation == service::strQuery); @@ -215,18 +213,18 @@ void SchemaLoader::validateSchema() if (itr == _objectNames.cend()) { - std::ostringstream error; auto itrPosition = _typePositions.find(entry.type); - - error << "Unknown type: " << objectName << " included by: " << entry.type; + auto error = + std::format("Unknown type: {} included by: {}", objectName, entry.type); if (itrPosition != _typePositions.cend()) { - error << " line: " << itrPosition->second.line - << " column: " << itrPosition->second.column; + error += std::format(" line: {} column: {}", + itrPosition->second.line, + itrPosition->second.column); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } _objectTypes[itr->second].unions.push_back(entry.type); @@ -265,16 +263,16 @@ void SchemaLoader::fixupOutputFieldList(OutputFieldList& fields, if (itr == _schemaTypes.cend()) { - std::ostringstream error; - - error << "Unknown field type: " << entry.type; + auto error = std::format("Unknown field type: {}", entry.type); if (entry.position) { - error << " line: " << entry.position->line << " column: " << entry.position->column; + error += std::format(" line: {} column: {}", + entry.position->line, + entry.position->column); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } switch (itr->second) @@ -301,17 +299,16 @@ void SchemaLoader::fixupOutputFieldList(OutputFieldList& fields, default: { - std::ostringstream error; - - error << "Invalid field type: " << entry.type; + auto error = std::format("Invalid field type: {}", entry.type); if (entry.position) { - error << " line: " << entry.position->line - << " column: " << entry.position->column; + error += std::format(" line: {} column: {}", + entry.position->line, + entry.position->column); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } } @@ -332,16 +329,16 @@ void SchemaLoader::fixupInputFieldList(InputFieldList& fields) if (itr == _schemaTypes.cend()) { - std::ostringstream error; - - error << "Unknown argument type: " << entry.type; + auto error = std::format("Unknown argument type: {}", entry.type); if (entry.position) { - error << " line: " << entry.position->line << " column: " << entry.position->column; + error += std::format(" line: {} column: {}", + entry.position->line, + entry.position->column); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } switch (itr->second) @@ -360,17 +357,16 @@ void SchemaLoader::fixupInputFieldList(InputFieldList& fields) default: { - std::ostringstream error; - - error << "Invalid argument type: " << entry.type; + auto error = std::format("Invalid argument type: {}", entry.type); if (entry.position) { - error << " line: " << entry.position->line - << " column: " << entry.position->column; + error += std::format(" line: {} column: {}", + entry.position->line, + entry.position->column); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } } } @@ -417,11 +413,9 @@ void SchemaLoader::reorderInputTypeDependencies() // Check to make sure we made progress. if (itrDependent == itr) { - std::ostringstream error; - - error << "Input object cycle type: " << itr->type; + const auto error = std::format("Input object cycle type: {}", itr->type); - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } if (itrDependent != _inputTypes.end()) @@ -534,12 +528,11 @@ void SchemaLoader::visitDefinition(const peg::ast_node& definition) else { const auto position = definition.begin(); - std::ostringstream error; + const auto error = std::format("Unexpected executable definition line: {} column: {}", + position.line, + position.column); - error << "Unexpected executable definition line: " << position.line - << " column: " << position.column; - - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } } @@ -1287,16 +1280,14 @@ void SchemaLoader::blockReservedName( // https://spec.graphql.org/October2021/#sec-Names.Reserved-Names if (name.size() > 1 && name.substr(0, 2) == R"gql(__)gql"sv) { - std::ostringstream error; - - error << "Names starting with __ are reserved: " << name; + auto error = std::format("Names starting with __ are reserved: {}", name); if (position) { - error << " line: " << position->line << " column: " << position->column; + error += std::format(" line: {} column: {}", position->line, position->column); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } } @@ -1307,18 +1298,18 @@ const InterfaceType& SchemaLoader::findInterfaceType( if (itrType == _interfaceNames.cend()) { - std::ostringstream error; const auto itrPosition = _typePositions.find(typeName); - - error << "Unknown interface: " << interfaceName << " implemented by: " << typeName; + auto error = + std::format("Unknown interface: {} implemented by: {}", interfaceName, typeName); if (itrPosition != _typePositions.cend()) { - error << " line: " << itrPosition->second.line - << " column: " << itrPosition->second.column; + error += std::format(" line: {} column: {}", + itrPosition->second.line, + itrPosition->second.column); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } return _interfaceTypes[itrType->second]; @@ -1342,24 +1333,24 @@ void SchemaLoader::validateInterfaceFields(std::string_view typeName, if (!unimplemented.empty()) { - std::ostringstream error; const auto itrPosition = _typePositions.find(typeName); - - error << "Missing interface fields type: " << typeName - << " interface: " << interfaceType.type; + auto error = std::format("Missing interface fields type: {} interface: {}", + typeName, + interfaceType.type); if (itrPosition != _typePositions.cend()) { - error << " line: " << itrPosition->second.line - << " column: " << itrPosition->second.column; + error += std::format(" line: {} column: {}", + itrPosition->second.line, + itrPosition->second.column); } for (auto fieldName : unimplemented) { - error << " field: " << fieldName; + error += std::format(" field: {}", fieldName); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } } @@ -1382,18 +1373,17 @@ void SchemaLoader::validateTransitiveInterfaces( if (unimplemented.find(typeName) != unimplemented.cend()) { - std::ostringstream error; const auto itrPosition = _typePositions.find(typeName); - - error << "Interface cycle interface: " << typeName; + auto error = std::format("Interface cycle interface: {}", typeName); if (itrPosition != _typePositions.cend()) { - error << " line: " << itrPosition->second.line - << " column: " << itrPosition->second.column; + error += std::format(" line: {} column: {}", + itrPosition->second.line, + itrPosition->second.column); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } for (auto entry : interfaces) @@ -1403,23 +1393,22 @@ void SchemaLoader::validateTransitiveInterfaces( if (!unimplemented.empty()) { - std::ostringstream error; const auto itrPosition = _typePositions.find(typeName); - - error << "Missing transitive interface type: " << typeName; + auto error = std::format("Missing transitive interface type: {}", typeName); if (itrPosition != _typePositions.cend()) { - error << " line: " << itrPosition->second.line - << " column: " << itrPosition->second.column; + error += std::format(" line: {} column: {}", + itrPosition->second.line, + itrPosition->second.column); } for (auto interfaceName : unimplemented) { - error << " interface: " << interfaceName; + error += std::format(" interface: {}", interfaceName); } - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } } @@ -1548,13 +1537,13 @@ InputFieldList SchemaLoader::getInputFields(const peg::ast_node::children_t& fie && (field.modifiers.empty() || field.modifiers.front() != service::TypeModifier::Nullable)) { - std::ostringstream error; - - error << "Expected Non-Null default value for field name: " << field.name - << " line: " << defaultValueLocation.line - << " column: " << defaultValueLocation.column; + const auto error = std::format( + "Expected Non-Null default value for field name: {} line: {} column: {}", + field.name, + defaultValueLocation.line, + defaultValueLocation.column); - throw std::runtime_error(error.str()); + throw std::runtime_error(error); } inputFields.push_back(std::move(field)); diff --git a/src/SyntaxTree.cpp b/src/SyntaxTree.cpp index b0882ac1..f51dc4d3 100644 --- a/src/SyntaxTree.cpp +++ b/src/SyntaxTree.cpp @@ -9,12 +9,12 @@ #include #include +#include #include #include #include #include #include -#include #include using namespace std::literals; @@ -51,7 +51,7 @@ std::string_view ast_node::unescaped_view() const && child->children.front()->is_type() && child->children.back()->is_type()) ? std::make_optional(std::make_pair(child->children.front()->string_view(), - child->children.back()->unescaped_view())) + child->children.back()->unescaped_view())) : std::nullopt; }); @@ -674,12 +674,11 @@ struct ast_action : maybe_nothing depth_guard guard(in.selectionSetDepth); if (in.selectionSetDepth > in.depthLimit()) { - std::ostringstream oss; + const auto error = std::format("Exceeded nested depth limit: {} for " + "https://spec.graphql.org/October2021/#SelectionSet", + in.depthLimit()); - oss << "Exceeded nested depth limit: " << in.depthLimit() - << " for https://spec.graphql.org/October2021/#SelectionSet"; - - throw parse_error(oss.str(), in); + throw parse_error(error, in); } return tao::graphqlpeg::template match(in, st...); diff --git a/src/Validation.cpp b/src/Validation.cpp index 65204d9e..c560c8b3 100644 --- a/src/Validation.cpp +++ b/src/Validation.cpp @@ -246,11 +246,9 @@ void ValidateArgumentValueVisitor::visitObjectValue(const peg::ast_node& objectV { // https://spec.graphql.org/October2021/#sec-Input-Object-Field-Uniqueness auto fieldPosition = field->begin(); - std::ostringstream message; + auto message = std::format("Conflicting input field name: {}", name); - message << "Conflicting input field name: " << name; - - _errors.push_back({ message.str(), { fieldPosition.line, fieldPosition.column } }); + _errors.push_back({ std::move(message), { fieldPosition.line, fieldPosition.column } }); continue; } @@ -494,11 +492,9 @@ void ValidateExecutableVisitor::visit(const peg::ast_node& root) { // https://spec.graphql.org/October2021/#sec-Fragment-Name-Uniqueness auto position = fragmentDefinition.begin(); - std::ostringstream error; - - error << "Duplicate fragment name: " << inserted.first->first; + auto error = std::format("Duplicate fragment name: {}", inserted.first->first); - _errors.push_back({ error.str(), { position.line, position.column } }); + _errors.push_back({ std::move(error), { position.line, position.column } }); } }); @@ -518,11 +514,9 @@ void ValidateExecutableVisitor::visit(const peg::ast_node& root) { // https://spec.graphql.org/October2021/#sec-Operation-Name-Uniqueness auto position = operationDefinition.begin(); - std::ostringstream error; - - error << "Duplicate operation name: " << inserted.first->first; + auto error = std::format("Duplicate operation name: {}", inserted.first->first); - _errors.push_back({ error.str(), { position.line, position.column } }); + _errors.push_back({ std::move(error), { position.line, position.column } }); } }); @@ -579,11 +573,10 @@ void ValidateExecutableVisitor::visit(const peg::ast_node& root) std::back_inserter(_errors), [](const auto& fragmentDefinition) noexcept { auto position = fragmentDefinition.second.get().begin(); - std::ostringstream message; + auto message = + std::format("Unused fragment definition name: {}", fragmentDefinition.first); - message << "Unused fragment definition name: " << fragmentDefinition.first; - - return schema_error { message.str(), { position.line, position.column } }; + return schema_error { std::move(message), { position.line, position.column } }; }); } } @@ -619,13 +612,12 @@ void ValidateExecutableVisitor::visitFragmentDefinition(const peg::ast_node& fra // https://spec.graphql.org/October2021/#sec-Fragment-Spread-Type-Existence // https://spec.graphql.org/October2021/#sec-Fragments-On-Composite-Types auto position = typeCondition->begin(); - std::ostringstream message; - - message << (itrType == _types.end() ? "Undefined target type on fragment definition: " - : "Scalar target type on fragment definition: ") - << name << " name: " << innerType; + auto message = std::format("{} target type on fragment definition: {} name: {}", + (itrType == _types.end() ? "Undefined" : "Scalar"), + name, + innerType); - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); return; } @@ -657,100 +649,94 @@ void ValidateExecutableVisitor::visitOperationDefinition(const peg::ast_node& op _operationVariables = std::make_optional(); - peg::for_each_child(operationDefinition, - [this, operationName](const peg::ast_node& variable) { - std::string_view variableName; - ValidateArgument variableArgument; + peg::for_each_child< + peg::variable>(operationDefinition, [this, operationName](const peg::ast_node& variable) { + std::string_view variableName; + ValidateArgument variableArgument; - for (const auto& child : variable.children) + for (const auto& child : variable.children) + { + if (child->is_type()) { - if (child->is_type()) + // Skip the $ prefix + variableName = child->string_view().substr(1); + + if (_operationVariables->find(variableName) != _operationVariables->end()) { - // Skip the $ prefix - variableName = child->string_view().substr(1); + // https://spec.graphql.org/October2021/#sec-Variable-Uniqueness + auto position = child->begin(); + auto message = "Conflicting variable"s; - if (_operationVariables->find(variableName) != _operationVariables->end()) + if (!operationName.empty()) { - // https://spec.graphql.org/October2021/#sec-Variable-Uniqueness - auto position = child->begin(); - std::ostringstream message; + message += std::format(" operation: {}", operationName); + } - message << "Conflicting variable"; + message += std::format(" name: {}", variableName); - if (!operationName.empty()) - { - message << " operation: " << operationName; - } + _errors.push_back({ std::move(message), { position.line, position.column } }); + return; + } + } + else if (child->is_type() || child->is_type() + || child->is_type()) + { + ValidateVariableTypeVisitor visitor(_schema, _types); - message << " name: " << variableName; + visitor.visit(*child); - _errors.push_back({ message.str(), { position.line, position.column } }); - return; - } - } - else if (child->is_type() || child->is_type() - || child->is_type()) + if (!visitor.isInputType()) { - ValidateVariableTypeVisitor visitor(_schema, _types); + // https://spec.graphql.org/October2021/#sec-Variables-Are-Input-Types + auto position = child->begin(); + auto message = "Invalid variable type"s; - visitor.visit(*child); - - if (!visitor.isInputType()) + if (!operationName.empty()) { - // https://spec.graphql.org/October2021/#sec-Variables-Are-Input-Types - auto position = child->begin(); - std::ostringstream message; - - message << "Invalid variable type"; - - if (!operationName.empty()) - { - message << " operation: " << operationName; - } - - message << " name: " << variableName; - - _errors.push_back({ message.str(), { position.line, position.column } }); - return; + message += std::format(" operation: {}", operationName); } - variableArgument.type = visitor.getType(); - } - else if (child->is_type()) - { - ValidateArgumentValueVisitor visitor(_errors); - - visitor.visit(*child->children.back()); + message += std::format(" name: {}", variableName); - auto argument = visitor.getArgumentValue(); + _errors.push_back({ std::move(message), { position.line, position.column } }); + return; + } - if (!validateInputValue(false, argument, variableArgument.type)) - { - // https://spec.graphql.org/October2021/#sec-Values-of-Correct-Type - auto position = child->begin(); - std::ostringstream message; + variableArgument.type = visitor.getType(); + } + else if (child->is_type()) + { + ValidateArgumentValueVisitor visitor(_errors); - message << "Incompatible variable default value"; + visitor.visit(*child->children.back()); - if (!operationName.empty()) - { - message << " operation: " << operationName; - } + auto argument = visitor.getArgumentValue(); - message << " name: " << variableName; + if (!validateInputValue(false, argument, variableArgument.type)) + { + // https://spec.graphql.org/October2021/#sec-Values-of-Correct-Type + auto position = child->begin(); + auto message = "Incompatible variable default value"s; - _errors.push_back({ message.str(), { position.line, position.column } }); - return; + if (!operationName.empty()) + { + message += std::format(" operation: {}", operationName); } - variableArgument.defaultValue = true; - variableArgument.nonNullDefaultValue = argument.value != nullptr; + message += std::format(" name: {}", variableName); + + _errors.push_back({ std::move(message), { position.line, position.column } }); + return; } + + variableArgument.defaultValue = true; + variableArgument.nonNullDefaultValue = argument.value != nullptr; } + } - _variableDefinitions.emplace(variableName, variable); - _operationVariables->emplace(variableName, std::move(variableArgument)); - }); + _variableDefinitions.emplace(variableName, variable); + _operationVariables->emplace(variableName, std::move(variableArgument)); + }); peg::on_first_child(operationDefinition, [this, &operationType](const peg::ast_node& child) { @@ -773,11 +759,9 @@ void ValidateExecutableVisitor::visitOperationDefinition(const peg::ast_node& op if (itrType == _operationTypes.end()) { auto position = operationDefinition.begin(); - std::ostringstream error; + auto error = std::format("Unsupported operation type: {}", operationType); - error << "Unsupported operation type: " << operationType; - - _errors.push_back({ error.str(), { position.line, position.column } }); + _errors.push_back({ std::move(error), { position.line, position.column } }); return; } @@ -795,32 +779,28 @@ void ValidateExecutableVisitor::visitOperationDefinition(const peg::ast_node& op { // https://spec.graphql.org/October2021/#sec-Single-root-field auto position = operationDefinition.begin(); - std::ostringstream error; - - error << "Subscription with more than one root field"; + auto error = "Subscription with more than one root field"s; if (!operationName.empty()) { - error << " name: " << operationName; + error += std::format(" name: {}", operationName); } - _errors.push_back({ error.str(), { position.line, position.column } }); + _errors.push_back({ std::move(error), { position.line, position.column } }); } if (_introspectionFieldCount != 0) { // https://spec.graphql.org/October2021/#sec-Single-root-field auto position = operationDefinition.begin(); - std::ostringstream error; - - error << "Subscription with Introspection root field"; + auto error = "Subscription with Introspection root field"s; if (!operationName.empty()) { - error << " name: " << operationName; + error += std::format(" name: {}", operationName); } - _errors.push_back({ error.str(), { position.line, position.column } }); + _errors.push_back({ std::move(error), { position.line, position.column } }); } } @@ -834,11 +814,9 @@ void ValidateExecutableVisitor::visitOperationDefinition(const peg::ast_node& op { // https://spec.graphql.org/October2021/#sec-All-Variables-Used auto position = variable.second.get().begin(); - std::ostringstream error; - - error << "Unused variable name: " << variable.first; + auto error = std::format("Unused variable name: {}", variable.first); - _errors.push_back({ error.str(), { position.line, position.column } }); + _errors.push_back({ std::move(error), { position.line, position.column } }); } } @@ -948,11 +926,9 @@ bool ValidateExecutableVisitor::validateInputValue( if (itrVariable == _operationVariables->end()) { // https://spec.graphql.org/October2021/#sec-All-Variable-Uses-Defined - std::ostringstream message; - - message << "Undefined variable name: " << variable.name; + auto message = std::format("Undefined variable name: {}", variable.name); - _errors.push_back({ message.str(), argument.position }); + _errors.push_back({ std::move(message), argument.position }); return false; } @@ -1045,11 +1021,9 @@ bool ValidateExecutableVisitor::validateInputValue( if (!std::holds_alternative(argument.value->data)) { - std::ostringstream message; + auto message = std::format("Expected Input Object value name: {}", name); - message << "Expected Input Object value name: " << name; - - _errors.push_back({ message.str(), argument.position }); + _errors.push_back({ std::move(message), argument.position }); return false; } @@ -1057,11 +1031,9 @@ bool ValidateExecutableVisitor::validateInputValue( if (itrFields == _inputTypeFields.end()) { - std::ostringstream message; - - message << "Expected Input Object fields name: " << name; + auto message = std::format("Expected Input Object fields name: {}", name); - _errors.push_back({ message.str(), argument.position }); + _errors.push_back({ std::move(message), argument.position }); return false; } @@ -1076,12 +1048,11 @@ bool ValidateExecutableVisitor::validateInputValue( if (itrField == itrFields->second.end()) { // https://spec.graphql.org/October2021/#sec-Input-Object-Field-Names - std::ostringstream message; + auto message = std::format("Undefined Input Object field type: {} name: {}", + name, + entry.first); - message << "Undefined Input Object field type: " << name - << " name: " << entry.first; - - _errors.push_back({ message.str(), entry.second.position }); + _errors.push_back({ std::move(message), entry.second.position }); return false; } @@ -1113,12 +1084,11 @@ bool ValidateExecutableVisitor::validateInputValue( if (!entry.second.type) { - std::ostringstream message; - - message << "Unknown Input Object field type: " << name - << " name: " << entry.first; + auto message = std::format("Unknown Input Object field type: {} name: {}", + name, + entry.first); - _errors.push_back({ message.str(), argument.position }); + _errors.push_back({ std::move(message), argument.position }); return false; } @@ -1127,12 +1097,11 @@ bool ValidateExecutableVisitor::validateInputValue( if (fieldKind == introspection::TypeKind::NON_NULL) { // https://spec.graphql.org/October2021/#sec-Input-Object-Required-Fields - std::ostringstream message; - - message << "Missing Input Object field type: " << name - << " name: " << entry.first; + auto message = std::format("Missing Input Object field type: {} name: {}", + name, + entry.first); - _errors.push_back({ message.str(), argument.position }); + _errors.push_back({ std::move(message), argument.position }); return false; } } @@ -1152,11 +1121,9 @@ bool ValidateExecutableVisitor::validateInputValue( if (!std::holds_alternative(argument.value->data)) { - std::ostringstream message; + auto message = std::format("Expected Enum value name: {}", name); - message << "Expected Enum value name: " << name; - - _errors.push_back({ message.str(), argument.position }); + _errors.push_back({ std::move(message), argument.position }); return false; } @@ -1166,11 +1133,9 @@ bool ValidateExecutableVisitor::validateInputValue( if (itrEnumValues == _enumValues.end() || itrEnumValues->second.find(value) == itrEnumValues->second.end()) { - std::ostringstream message; - - message << "Undefined Enum value type: " << name << " name: " << value; + auto message = std::format("Undefined Enum value type: {} name: {}", name, value); - _errors.push_back({ message.str(), argument.position }); + _errors.push_back({ std::move(message), argument.position }); return false; } @@ -1231,11 +1196,9 @@ bool ValidateExecutableVisitor::validateInputValue( if (_scalarTypes.find(name) == _scalarTypes.end()) { - std::ostringstream message; + auto message = std::format("Undefined Scalar type name: {}", name); - message << "Undefined Scalar type name: " << name; - - _errors.push_back({ message.str(), argument.position }); + _errors.push_back({ std::move(message), argument.position }); return false; } @@ -1398,11 +1361,10 @@ bool ValidateExecutableVisitor::validateVariableType(bool isNonNull, if (variableName != inputName) { // https://spec.graphql.org/October2021/#sec-All-Variable-Usages-are-Allowed - std::ostringstream message; - - message << "Incompatible variable type: " << variableName << " name: " << inputName; + auto message = + std::format("Incompatible variable type: {} name: {}", variableName, inputName); - _errors.push_back({ message.str(), position }); + _errors.push_back({ std::move(message), position }); return false; } @@ -1563,11 +1525,10 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) { // https://spec.graphql.org/October2021/#sec-Leaf-Field-Selections auto position = field.begin(); - std::ostringstream message; + auto message = + std::format("Field on scalar type: {} name: {}", _scopedType->get().name(), name); - message << "Field on scalar type: " << _scopedType->get().name() << " name: " << name; - - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); return; } @@ -1591,12 +1552,11 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) { // https://spec.graphql.org/October2021/#sec-Leaf-Field-Selections auto position = field.begin(); - std::ostringstream message; - - message << "Field on union type: " << _scopedType->get().name() - << " name: " << name; + auto message = std::format("Field on union type: {} name: {}", + _scopedType->get().name(), + name); - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); return; } @@ -1615,11 +1575,10 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) { // https://spec.graphql.org/October2021/#sec-Field-Selections auto position = field.begin(); - std::ostringstream message; + auto message = + std::format("Undefined field type: {} name: {}", _scopedType->get().name(), name); - message << "Undefined field type: " << _scopedType->get().name() << " name: " << name; - - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); return; } @@ -1649,12 +1608,12 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) if (validateArguments.find(argumentName) != validateArguments.end()) { // https://spec.graphql.org/October2021/#sec-Argument-Uniqueness - std::ostringstream message; - - message << "Conflicting argument type: " << _scopedType->get().name() - << " field: " << name << " name: " << argumentName; + auto message = std::format("Conflicting argument type: {} field: {} name: {}", + _scopedType->get().name(), + name, + argumentName); - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); continue; } @@ -1687,11 +1646,10 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) { // https://spec.graphql.org/October2021/#sec-Field-Selection-Merging auto position = field.begin(); - std::ostringstream message; - - message << "Conflicting field type: " << _scopedType->get().name() << " name: " << name; + auto message = + std::format("Conflicting field type: {} name: {}", _scopedType->get().name(), name); - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); } } @@ -1706,12 +1664,12 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) if (itrArgument == itrField->second.arguments.end()) { // https://spec.graphql.org/October2021/#sec-Argument-Names - std::ostringstream message; + auto message = std::format("Undefined argument type: {} field: {} name: {}", + _scopedType->get().name(), + name, + argumentName); - message << "Undefined argument type: " << _scopedType->get().name() - << " field: " << name << " name: " << argumentName; - - _errors.push_back({ message.str(), argumentLocations[argumentName] }); + _errors.push_back({ std::move(message), argumentLocations[argumentName] }); } } @@ -1728,12 +1686,12 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) argument.second.type)) { // https://spec.graphql.org/October2021/#sec-Values-of-Correct-Type - std::ostringstream message; - - message << "Incompatible argument type: " << _scopedType->get().name() - << " field: " << name << " name: " << argument.first; + auto message = std::format("Incompatible argument type: {} field: {} name: {}", + _scopedType->get().name(), + name, + argument.first); - _errors.push_back({ message.str(), argumentLocations[argument.first] }); + _errors.push_back({ std::move(message), argumentLocations[argument.first] }); } continue; @@ -1750,14 +1708,13 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) { // https://spec.graphql.org/October2021/#sec-Required-Arguments auto position = field.begin(); - std::ostringstream message; + auto message = std::format("{} argument type: {} field: {} name: {}", + (missing ? "Missing" : "Required non-null"), + _scopedType->get().name(), + name, + argument.first); - message << (missing ? "Missing argument type: " - : "Required non-null argument type: ") - << _scopedType->get().name() << " field: " << name - << " name: " << argument.first; - - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); } } } @@ -1798,11 +1755,10 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) { // https://spec.graphql.org/October2021/#sec-Leaf-Field-Selections auto position = field.begin(); - std::ostringstream message; - - message << "Missing fields on non-scalar type: " << innerType->get().name(); + auto message = + std::format("Missing fields on non-scalar type: {}", innerType->get().name()); - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); return; } @@ -1830,11 +1786,9 @@ void ValidateExecutableVisitor::visitFragmentSpread(const peg::ast_node& fragmen { // https://spec.graphql.org/October2021/#sec-Fragment-spread-target-defined auto position = fragmentSpread.begin(); - std::ostringstream message; - - message << "Undefined fragment spread name: " << name; + auto message = std::format("Undefined fragment spread name: {}", name); - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); return; } @@ -1844,11 +1798,9 @@ void ValidateExecutableVisitor::visitFragmentSpread(const peg::ast_node& fragmen { // https://spec.graphql.org/October2021/#sec-Fragment-spreads-must-not-form-cycles auto position = fragmentSpread.begin(); - std::ostringstream message; + auto message = std::format("Cyclic fragment spread name: {}", name); - message << "Cyclic fragment spread name: " << name; - - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); } return; @@ -1863,11 +1815,10 @@ void ValidateExecutableVisitor::visitFragmentSpread(const peg::ast_node& fragmen { // https://spec.graphql.org/October2021/#sec-Fragment-spread-is-possible auto position = fragmentSpread.begin(); - std::ostringstream message; - - message << "Incompatible fragment spread target type: " << innerType << " name: " << name; + auto message = + std::format("Incompatible fragment spread target type: {} name: {}", innerType, name); - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); return; } @@ -1914,11 +1865,10 @@ void ValidateExecutableVisitor::visitInlineFragment(const peg::ast_node& inlineF if (itrInner == _types.end()) { // https://spec.graphql.org/October2021/#sec-Fragment-Spread-Type-Existence - std::ostringstream message; + auto message = + std::format("Undefined target type on inline fragment name: {}", innerType); - message << "Undefined target type on inline fragment name: " << innerType; - - _errors.push_back({ message.str(), std::move(typeConditionLocation) }); + _errors.push_back({ std::move(message), std::move(typeConditionLocation) }); return; } @@ -1928,14 +1878,11 @@ void ValidateExecutableVisitor::visitInlineFragment(const peg::ast_node& inlineF { // https://spec.graphql.org/October2021/#sec-Fragments-On-Composite-Types // https://spec.graphql.org/October2021/#sec-Fragment-spread-is-possible - std::ostringstream message; - - message << (isScalarType(fragmentType->get().kind()) - ? "Scalar target type on inline fragment name: " - : "Incompatible target type on inline fragment name: ") - << innerType; + auto message = std::format("{} target type on inline fragment name: {}", + (isScalarType(fragmentType->get().kind()) ? "Scalar" : "Incompatible"), + innerType); - _errors.push_back({ message.str(), std::move(typeConditionLocation) }); + _errors.push_back({ std::move(message), std::move(typeConditionLocation) }); return; } } @@ -1972,11 +1919,9 @@ void ValidateExecutableVisitor::visitDirectives( { // https://spec.graphql.org/October2021/#sec-Directives-Are-Defined auto position = directive->begin(); - std::ostringstream message; - - message << "Undefined directive name: " << directiveName; + auto message = std::format("Undefined directive name: {}", directiveName); - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); continue; } @@ -1984,11 +1929,9 @@ void ValidateExecutableVisitor::visitDirectives( { // https://spec.graphql.org/October2021/#sec-Directives-Are-Unique-Per-Location auto position = directive->begin(); - std::ostringstream message; + auto message = std::format("Conflicting directive name: {}", directiveName); - message << "Conflicting directive name: " << directiveName; - - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); continue; } @@ -1996,45 +1939,43 @@ void ValidateExecutableVisitor::visitDirectives( { // https://spec.graphql.org/October2021/#sec-Directives-Are-In-Valid-Locations auto position = directive->begin(); - std::ostringstream message; - - message << "Unexpected location for directive: " << directiveName; + auto message = std::format("Unexpected location for directive: {}", directiveName); switch (location) { case introspection::DirectiveLocation::QUERY: - message << " name: QUERY"; + message += " name: QUERY"; break; case introspection::DirectiveLocation::MUTATION: - message << " name: MUTATION"; + message += " name: MUTATION"; break; case introspection::DirectiveLocation::SUBSCRIPTION: - message << " name: SUBSCRIPTION"; + message += " name: SUBSCRIPTION"; break; case introspection::DirectiveLocation::FIELD: - message << " name: FIELD"; + message += " name: FIELD"; break; case introspection::DirectiveLocation::FRAGMENT_DEFINITION: - message << " name: FRAGMENT_DEFINITION"; + message += " name: FRAGMENT_DEFINITION"; break; case introspection::DirectiveLocation::FRAGMENT_SPREAD: - message << " name: FRAGMENT_SPREAD"; + message += " name: FRAGMENT_SPREAD"; break; case introspection::DirectiveLocation::INLINE_FRAGMENT: - message << " name: INLINE_FRAGMENT"; + message += " name: INLINE_FRAGMENT"; break; default: break; } - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back({ std::move(message), { position.line, position.column } }); continue; } @@ -2052,12 +1993,12 @@ void ValidateExecutableVisitor::visitDirectives( if (validateArguments.find(argumentName) != validateArguments.end()) { // https://spec.graphql.org/October2021/#sec-Argument-Uniqueness - std::ostringstream message; + auto message = std::format("Conflicting argument directive: {} name: {}", + directiveName, + argumentName); - message << "Conflicting argument directive: " << directiveName - << " name: " << argumentName; - - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back( + { std::move(message), { position.line, position.column } }); continue; } @@ -2076,12 +2017,11 @@ void ValidateExecutableVisitor::visitDirectives( if (itrArgument == itrDirective->second.arguments.end()) { // https://spec.graphql.org/October2021/#sec-Argument-Names - std::ostringstream message; - - message << "Undefined argument directive: " << directiveName - << " name: " << argumentName; + auto message = std::format("Undefined argument directive: {} name: {}", + directiveName, + argumentName); - _errors.push_back({ message.str(), argumentLocations[argumentName] }); + _errors.push_back({ std::move(message), argumentLocations[argumentName] }); } } @@ -2098,12 +2038,13 @@ void ValidateExecutableVisitor::visitDirectives( argument.second.type)) { // https://spec.graphql.org/October2021/#sec-Values-of-Correct-Type - std::ostringstream message; + auto message = + std::format("Incompatible argument directive: {} name: {}", + directiveName, + argument.first); - message << "Incompatible argument directive: " << directiveName - << " name: " << argument.first; - - _errors.push_back({ message.str(), argumentLocations[argument.first] }); + _errors.push_back( + { std::move(message), argumentLocations[argument.first] }); } continue; @@ -2120,13 +2061,13 @@ void ValidateExecutableVisitor::visitDirectives( { // https://spec.graphql.org/October2021/#sec-Required-Arguments auto position = directive->begin(); - std::ostringstream message; - - message << (missing ? "Missing argument directive: " - : "Required non-null argument directive: ") - << directiveName << " name: " << argument.first; + auto message = std::format("{} argument directive: {} name: {}", + (missing ? "Missing" : "Required non-null"), + directiveName, + argument.first); - _errors.push_back({ message.str(), { position.line, position.column } }); + _errors.push_back( + { std::move(message), { position.line, position.column } }); } } }); diff --git a/src/introspection/DirectiveObject.cpp b/src/introspection/DirectiveObject.cpp index 7f1c19be..4da18e52 100644 --- a/src/introspection/DirectiveObject.cpp +++ b/src/introspection/DirectiveObject.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/src/introspection/EnumValueObject.cpp b/src/introspection/EnumValueObject.cpp index 85ff0ca5..7cdb6386 100644 --- a/src/introspection/EnumValueObject.cpp +++ b/src/introspection/EnumValueObject.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include diff --git a/src/introspection/FieldObject.cpp b/src/introspection/FieldObject.cpp index cd50b6b6..4a6dc359 100644 --- a/src/introspection/FieldObject.cpp +++ b/src/introspection/FieldObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/src/introspection/InputValueObject.cpp b/src/introspection/InputValueObject.cpp index daef5e94..40fa9620 100644 --- a/src/introspection/InputValueObject.cpp +++ b/src/introspection/InputValueObject.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/src/introspection/IntrospectionSchema.cpp b/src/introspection/IntrospectionSchema.cpp index 048cbcc9..f735c21d 100644 --- a/src/introspection/IntrospectionSchema.cpp +++ b/src/introspection/IntrospectionSchema.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/src/introspection/SchemaObject.cpp b/src/introspection/SchemaObject.cpp index 49199c42..142e39ec 100644 --- a/src/introspection/SchemaObject.cpp +++ b/src/introspection/SchemaObject.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/src/introspection/TypeObject.cpp b/src/introspection/TypeObject.cpp index e7b13ff8..8c1fafce 100644 --- a/src/introspection/TypeObject.cpp +++ b/src/introspection/TypeObject.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include From 79af047030fc3769c1bc9c7b66e01eddb3875362 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 16 Sep 2024 22:30:32 -0700 Subject: [PATCH 069/123] fix(fmt): minor fixes following up to last change --- src/GraphQLService.cpp | 2 +- src/Validation.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index ab84142a..9b704d8b 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -1082,7 +1082,7 @@ void SelectionVisitor::visitField(const peg::ast_node& field) catch (const std::exception& ex) { std::promise promise; - auto message = std::format("Field error name: {} unknown error: ", alias, ex.what()); + auto message = std::format("Field error name: {} unknown error: {}", alias, ex.what()); promise.set_exception( std::make_exception_ptr(schema_exception { { schema_error { std::move(message), diff --git a/src/Validation.cpp b/src/Validation.cpp index c560c8b3..a065fad1 100644 --- a/src/Validation.cpp +++ b/src/Validation.cpp @@ -1944,31 +1944,31 @@ void ValidateExecutableVisitor::visitDirectives( switch (location) { case introspection::DirectiveLocation::QUERY: - message += " name: QUERY"; + message += " name: QUERY"sv; break; case introspection::DirectiveLocation::MUTATION: - message += " name: MUTATION"; + message += " name: MUTATION"sv; break; case introspection::DirectiveLocation::SUBSCRIPTION: - message += " name: SUBSCRIPTION"; + message += " name: SUBSCRIPTION"sv; break; case introspection::DirectiveLocation::FIELD: - message += " name: FIELD"; + message += " name: FIELD"sv; break; case introspection::DirectiveLocation::FRAGMENT_DEFINITION: - message += " name: FRAGMENT_DEFINITION"; + message += " name: FRAGMENT_DEFINITION"sv; break; case introspection::DirectiveLocation::FRAGMENT_SPREAD: - message += " name: FRAGMENT_SPREAD"; + message += " name: FRAGMENT_SPREAD"sv; break; case introspection::DirectiveLocation::INLINE_FRAGMENT: - message += " name: INLINE_FRAGMENT"; + message += " name: INLINE_FRAGMENT"sv; break; default: From 7cee86d883de943c94538349a53bd2cb9f577eb4 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 17 Sep 2024 15:36:02 -0700 Subject: [PATCH 070/123] feat(json): default taocpp-json impl for graphqljson --- .github/workflows/linux.yml | 2 +- CMakeLists.txt | 11 +- src/CMakeLists.txt | 23 +- ...JSONResponse.cpp => RapidJSONResponse.cpp} | 6 +- src/TaoCppJSONResponse.cpp | 260 ++++++++++++++++++ vcpkg.json | 8 +- 6 files changed, 290 insertions(+), 20 deletions(-) rename src/{JSONResponse.cpp => RapidJSONResponse.cpp} (96%) create mode 100644 src/TaoCppJSONResponse.cpp diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 048858ca..a0b933a3 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -35,7 +35,7 @@ jobs: run: cmake -E make_directory build - name: Configure CMake - run: cmake --preset ${{ matrix.compiler }}-${{ matrix.config }} -DCMAKE_TOOLCHAIN_FILE= + run: cmake --preset ${{ matrix.compiler }}-${{ matrix.config }} -DGRAPHQL_USE_TAOCPP_JSON=OFF -DCMAKE_TOOLCHAIN_FILE= - name: Build run: cmake --build --preset ${{ matrix.compiler }}-${{ matrix.config }} -j -v diff --git a/CMakeLists.txt b/CMakeLists.txt index 753aca8a..0b1f7a31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ option(GRAPHQL_BUILD_MODULES "Build the C++20 module interface libraries." ON) option(GRAPHQL_BUILD_SCHEMAGEN "Build the schemagen tool." ON) option(GRAPHQL_BUILD_CLIENTGEN "Build the clientgen tool." ON) option(GRAPHQL_BUILD_TESTS "Build the tests and sample schema library." ON) -option(GRAPHQL_USE_RAPIDJSON "Use RapidJSON for JSON serialization." ON) +option(GRAPHQL_USE_TAOCPP_JSON "Use taocpp-json for JSON serialization." ON) if(GRAPHQL_BUILD_SCHEMAGEN) list(APPEND VCPKG_MANIFEST_FEATURES "schemagen") @@ -51,8 +51,13 @@ if(GRAPHQL_BUILD_TESTS) list(APPEND VCPKG_MANIFEST_FEATURES "tests") endif() -if(GRAPHQL_USE_RAPIDJSON) - list(APPEND VCPKG_MANIFEST_FEATURES "rapidjson") +if(GRAPHQL_USE_TAOCPP_JSON) + list(APPEND VCPKG_MANIFEST_FEATURES "taocpp-json") +else() + option(GRAPHQL_USE_RAPIDJSON "Use RapidJSON for JSON serialization." ON) + if(GRAPHQL_USE_RAPIDJSON) + list(APPEND VCPKG_MANIFEST_FEATURES "rapidjson") + endif() endif() if(GRAPHQL_BUILD_SCHEMAGEN AND GRAPHQL_BUILD_CLIENTGEN) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64d1d21f..bc8f5b07 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -387,21 +387,22 @@ if(WIN32 AND BUILD_SHARED_LIBS) add_version_rc(graphqlclient) endif() -# RapidJSON is the only option for JSON serialization used in this project, but if you want -# to use another JSON library you can implement an alternate version of the functions in -# JSONResponse.cpp to serialize to and from GraphQLResponse and build graphqljson from that. -# You will also need to define how to build the graphqljson library target with your -# implementation, and you should set BUILD_GRAPHQLJSON so that the test dependencies know -# about your version of graphqljson. -if(GRAPHQL_USE_RAPIDJSON) +if(GRAPHQL_USE_TAOCPP_JSON) + find_package(taocpp-json CONFIG REQUIRED) + set(BUILD_GRAPHQLJSON ON) + add_library(graphqljson TaoCppJSONResponse.cpp) + target_link_libraries(graphqljson PRIVATE taocpp::json) +elseif(GRAPHQL_USE_RAPIDJSON) find_package(RapidJSON CONFIG REQUIRED) - set(BUILD_GRAPHQLJSON ON) - add_library(graphqljson JSONResponse.cpp) + add_library(graphqljson RapidJSONResponse.cpp) + target_include_directories(graphqljson SYSTEM PRIVATE ${RAPIDJSON_INCLUDE_DIRS}) +endif() + +if(BUILD_GRAPHQLJSON) add_library(cppgraphqlgen::graphqljson ALIAS graphqljson) target_compile_features(graphqljson PUBLIC cxx_std_20) target_link_libraries(graphqljson PUBLIC graphqlresponse) - target_include_directories(graphqljson SYSTEM PRIVATE ${RAPIDJSON_INCLUDE_DIRS}) target_sources(graphqljson PUBLIC FILE_SET HEADERS BASE_DIRS ${INCLUDE_ROOT} FILES ${INCLUDE_ROOT}/graphqlservice/JSONResponse.h) @@ -456,8 +457,6 @@ endif() # graphqljson if(BUILD_GRAPHQLJSON) - target_link_libraries(graphqljson PUBLIC graphqlresponse) - install(TARGETS graphqljson EXPORT cppgraphqlgen-targets RUNTIME DESTINATION bin diff --git a/src/JSONResponse.cpp b/src/RapidJSONResponse.cpp similarity index 96% rename from src/JSONResponse.cpp rename to src/RapidJSONResponse.cpp index 8f135478..e7067f61 100644 --- a/src/JSONResponse.cpp +++ b/src/RapidJSONResponse.cpp @@ -16,10 +16,10 @@ namespace graphql::response { -class StringWriter +class StreamWriter { public: - StringWriter(rapidjson::StringBuffer& buffer) + StreamWriter(rapidjson::StringBuffer& buffer) : _writer { buffer } { } @@ -81,7 +81,7 @@ class StringWriter std::string toJSON(Value&& response) { rapidjson::StringBuffer buffer; - Writer writer { std::make_unique(buffer) }; + Writer writer { std::make_unique(buffer) }; writer.write(std::move(response)); return buffer.GetString(); diff --git a/src/TaoCppJSONResponse.cpp b/src/TaoCppJSONResponse.cpp new file mode 100644 index 00000000..341327b8 --- /dev/null +++ b/src/TaoCppJSONResponse.cpp @@ -0,0 +1,260 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "graphqlservice/JSONResponse.h" + +#include + +#include +#include +#include +#include +#include + +namespace graphql::response { + +class StreamWriter +{ +public: + StreamWriter(std::ostream& stream) + : _writer { stream } + { + } + + void start_object() + { + _scopeStack.push_back(Scope::Object); + _writer.begin_object(); + } + + void add_member(const std::string& key) + { + _writer.key(key); + } + + void end_object() + { + _writer.end_object(); + _scopeStack.pop_back(); + end_value(); + } + + void start_array() + { + _scopeStack.push_back(Scope::Object); + _writer.begin_array(); + } + + void end_arrary() + { + _writer.end_array(); + _scopeStack.pop_back(); + end_value(); + } + + void write_null() + { + _writer.null(); + end_value(); + } + + void write_string(const std::string& value) + { + _writer.string(value); + end_value(); + } + + void write_bool(bool value) + { + _writer.boolean(value); + end_value(); + } + + void write_int(int value) + { + _writer.number(static_cast(value)); + end_value(); + } + + void write_float(double value) + { + _writer.number(value); + end_value(); + } + +private: + enum class Scope + { + Array, + Object, + }; + + void end_value() + { + if (_scopeStack.empty()) + { + return; + } + + switch (_scopeStack.back()) + { + case Scope::Array: + _writer.element(); + break; + + case Scope::Object: + _writer.member(); + break; + } + } + + tao::json::events::to_stream _writer; + std::vector _scopeStack; +}; + +std::string toJSON(Value&& response) +{ + std::ostringstream stream; + Writer writer { std::make_unique(stream) }; + writer.write(std::move(response)); + return stream.str(); +} + +struct ResponseHandler +{ + ResponseHandler() + { + // Start with a single null value. + _responseStack.push_back({}); + } + + Value getResponse() + { + auto response = std::move(_responseStack.back()); + + _responseStack.pop_back(); + + return response; + } + + void null() + { + setValue(Value()); + } + + void boolean(bool b) + { + setValue(Value(b)); + } + + void number(double d) + { + auto value = Value(Type::Float); + + value.set(std::move(d)); + setValue(std::move(value)); + } + + void number(std::int64_t i) + { + if (i < std::numeric_limits::min() + || i > std::numeric_limits::max()) + { + // https://spec.graphql.org/October2021/#sec-Int + number(static_cast(i)); + } + else + { + static_assert(sizeof(std::int32_t) == sizeof(IntType), + "GraphQL only supports 32-bit signed integers"); + auto value = Value(Type::Int); + + value.set(static_cast(i)); + setValue(std::move(value)); + } + } + + void number(std::uint64_t i) + { + if (i > static_cast(std::numeric_limits::max())) + { + // https://spec.graphql.org/October2021/#sec-Int + number(static_cast(i)); + } + else + { + number(static_cast(i)); + } + } + + void string(std::string&& str) + { + setValue(Value(std::move(str)).from_json()); + } + + void begin_array() + { + _responseStack.push_back(Value(Type::List)); + } + + void element() + { + } + + void end_array() + { + setValue(getResponse()); + } + + void begin_object() + { + _responseStack.push_back(Value(Type::Map)); + } + + void key(std::string&& str) + { + _keyStack.push_back(std::move(str)); + } + + void member() + { + } + + void end_object() + { + setValue(getResponse()); + } + +private: + void setValue(Value&& value) + { + switch (_responseStack.back().type()) + { + case Type::Map: + _responseStack.back().emplace_back(std::move(_keyStack.back()), std::move(value)); + _keyStack.pop_back(); + break; + + case Type::List: + _responseStack.back().emplace_back(std::move(value)); + break; + + default: + _responseStack.back() = std::move(value); + break; + } + } + + std::vector _keyStack; + std::vector _responseStack; +}; + +Value parseJSON(const std::string& json) +{ + ResponseHandler handler; + tao::json::events::from_string(handler, json); + + return handler.getResponse(); +} + +} // namespace graphql::response diff --git a/vcpkg.json b/vcpkg.json index 7c62b562..5ed83019 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -20,8 +20,14 @@ "gtest" ] }, + "taocpp-json": { + "description": "Build the graphqljson library with taocpp-json.", + "dependencies": [ + "taocpp-json" + ] + }, "rapidjson": { - "description": "Build the graphqljson library with RapidJSON.", + "description": "Build the graphqljson library with rapidjson.", "dependencies": [ "rapidjson" ] From 358b0421c53e476c2adcd41965ab5fbc0144bcfd Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 17 Sep 2024 17:32:30 -0700 Subject: [PATCH 071/123] fix(sample): using wrong member itr for variables --- samples/proxy/server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/proxy/server.cpp b/samples/proxy/server.cpp index cdb6e35b..6f43556d 100644 --- a/samples/proxy/server.cpp +++ b/samples/proxy/server.cpp @@ -161,8 +161,8 @@ int main() auto variables = (variablesItr != payload.end() && variablesItr->second.type() == response::Type::String) - ? response::parseJSON(operationNameItr->second - .get()) + ? response::parseJSON( + variablesItr->second.get()) : response::Value {}; msg = http::response { http::status::ok, From fa15fb7527dc4d9b2b8a425e2ebb9824a25d2e4d Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 18 Sep 2024 12:29:05 -0700 Subject: [PATCH 072/123] fix(coro): stop spawning waiter threads for async futures --- include/graphqlservice/GraphQLService.h | 59 +++---------------------- 1 file changed, 6 insertions(+), 53 deletions(-) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 1474e91a..381cae3f 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -342,40 +342,14 @@ class [[nodiscard("unnecessary construction")]] AwaitableScalar std::promise _promise; }; - [[nodiscard("unexpected call")]] bool await_ready() const noexcept + [[nodiscard("unexpected call")]] constexpr bool await_ready() const noexcept { - return std::visit( - [](const auto& value) noexcept { - using value_type = std::decay_t; - - if constexpr (std::is_same_v) - { - return true; - } - else if constexpr (std::is_same_v>) - { - using namespace std::literals; - - return value.wait_for(0s) != std::future_status::timeout; - } - else if constexpr (std::is_same_v>) - { - return true; - } - }, - _value); + return true; } void await_suspend(std::coroutine_handle<> h) const { - std::thread( - [this](std::coroutine_handle<> h) noexcept { - std::get>(_value).wait(); - h.resume(); - }, - std::move(h)) - .detach(); + h.resume(); } [[nodiscard("unnecessary construction")]] T await_resume() @@ -472,35 +446,14 @@ class [[nodiscard("unnecessary construction")]] AwaitableObject std::promise _promise; }; - [[nodiscard("unexpected call")]] bool await_ready() const noexcept + [[nodiscard("unexpected call")]] constexpr bool await_ready() const noexcept { - return std::visit( - [](const auto& value) noexcept { - using value_type = std::decay_t; - - if constexpr (std::is_same_v) - { - return true; - } - else if constexpr (std::is_same_v>) - { - using namespace std::literals; - - return value.wait_for(0s) != std::future_status::timeout; - } - }, - _value); + return true; } void await_suspend(std::coroutine_handle<> h) const { - std::thread( - [this](std::coroutine_handle<> h) noexcept { - std::get>(_value).wait(); - h.resume(); - }, - std::move(h)) - .detach(); + h.resume(); } [[nodiscard("unnecessary construction")]] T await_resume() From be112636c522ccb8945c744d0e94df9abee83cd7 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 18 Sep 2024 15:30:47 -0700 Subject: [PATCH 073/123] feat(sample): add non-trivial async field resolvers to proxy client --- samples/proxy/client.cpp | 128 ++++++++++++++++++-- samples/proxy/query/ProxyClient.cpp | 34 +++++- samples/proxy/query/ProxyClient.h | 13 +- samples/proxy/query/query.graphql | 5 +- samples/proxy/schema/ProxySchema.cpp | 3 + samples/proxy/schema/ProxySchema.h | 2 + samples/proxy/schema/ProxySchema.ixx | 2 + samples/proxy/schema/QueryObject.cpp | 5 +- samples/proxy/schema/QueryObject.h | 8 +- samples/proxy/schema/ResultsObject.cpp | 91 ++++++++++++++ samples/proxy/schema/ResultsObject.h | 154 ++++++++++++++++++++++++ samples/proxy/schema/ResultsObject.ixx | 16 +++ samples/proxy/schema/proxy_schema_files | 1 + samples/proxy/schema/schema.graphql | 7 +- 14 files changed, 450 insertions(+), 19 deletions(-) create mode 100644 samples/proxy/schema/ResultsObject.cpp create mode 100644 samples/proxy/schema/ResultsObject.h create mode 100644 samples/proxy/schema/ResultsObject.ixx diff --git a/samples/proxy/client.cpp b/samples/proxy/client.cpp index d8be65f5..61893e72 100644 --- a/samples/proxy/client.cpp +++ b/samples/proxy/client.cpp @@ -5,6 +5,7 @@ #include "schema/ProxySchema.h" #include "schema/QueryObject.h" +#include "schema/ResultsObject.h" #include "graphqlservice/JSONResponse.h" @@ -21,6 +22,7 @@ #include #include +#include #include #include #include @@ -45,13 +47,111 @@ constexpr auto c_port = "8080"sv; constexpr auto c_target = "/graphql"sv; constexpr int c_version = 11; // HTTP 1.1 +struct AsyncIoWorker : service::RequestState +{ + AsyncIoWorker() + : worker { std::make_shared() } + { + } + + const service::await_async worker; +}; + +class Results +{ +public: + explicit Results(response::Value&& data, std::vector errors) noexcept; + + service::AwaitableScalar> getData( + service::FieldParams&& fieldParams) const; + service::AwaitableScalar>>> getErrors( + service::FieldParams&& fieldParams) const; + +private: + mutable response::Value m_data; + mutable std::vector m_errors; +}; + +Results::Results(response::Value&& data, std::vector errors) noexcept + : m_data { std::move(data) } + , m_errors { std::move(errors) } +{ +} + +service::AwaitableScalar> Results::getData( + service::FieldParams&& fieldParams) const +{ + auto asyncIoWorker = std::static_pointer_cast(fieldParams.state); + auto data = std::move(m_data); + + // Jump to a worker thread for the resolver where we can run a separate I/O context without + // blocking the I/O context in Query::getRelay. This simulates how you might fan out to + // additional async I/O tasks for sub-field resolvers. + co_await asyncIoWorker->worker; + + net::io_context ioc; + auto future = net::co_spawn( + ioc, + [](response::Value&& data) -> net::awaitable> { + co_return (data.type() == response::Type::Null) + ? std::nullopt + : std::make_optional(response::toJSON(std::move(data))); + }(std::move(data)), + net::use_future); + + ioc.run(); + + co_return future.get(); +} + +service::AwaitableScalar>>> Results::getErrors( + service::FieldParams&& fieldParams) const +{ + auto asyncIoWorker = std::static_pointer_cast(fieldParams.state); + auto errors = std::move(m_errors); + + // Jump to a worker thread for the resolver where we can run a separate I/O context without + // blocking the I/O context in Query::getRelay. This simulates how you might fan out to + // additional async I/O tasks for sub-field resolvers. + co_await asyncIoWorker->worker; + + net::io_context ioc; + auto future = net::co_spawn( + ioc, + [](std::vector errors) + -> net::awaitable>>> { + if (errors.empty()) + { + co_return std::nullopt; + } + + std::vector> results { errors.size() }; + + std::transform(errors.begin(), + errors.end(), + results.begin(), + [](auto& error) noexcept -> std::optional { + return error.message.empty() + ? std::nullopt + : std::make_optional(std::move(error.message)); + }); + + co_return std::make_optional(results); + }(std::move(errors)), + net::use_future); + + ioc.run(); + + co_return future.get(); +} + class Query { public: explicit Query(std::string_view host, std::string_view port, std::string_view target, int version) noexcept; - std::future> getRelay(std::string&& queryArg, + std::future> getRelay(std::string&& queryArg, std::optional&& operationNameArg, std::optional&& variablesArg) const; @@ -73,7 +173,7 @@ Query::Query( // Based on: // https://www.boost.org/doc/libs/1_82_0/libs/beast/example/http/client/awaitable/http_client_awaitable.cpp -std::future> Query::getRelay(std::string&& queryArg, +std::future> Query::getRelay(std::string&& queryArg, std::optional&& operationNameArg, std::optional&& variablesArg) const { response::Value payload { response::Type::Map }; @@ -99,7 +199,7 @@ std::future> Query::getRelay(std::string&& queryArg, const char* port, const char* target, int version, - std::string requestBody) -> net::awaitable> { + std::string requestBody) -> net::awaitable> { // These objects perform our I/O. They use an executor with a default completion token // of use_awaitable. This makes our code easy, but will use exceptions as the default // error handling, i.e. if the connection drops, we might see an exception. @@ -150,7 +250,10 @@ std::future> Query::getRelay(std::string&& queryArg, throw boost::system::system_error(ec, "shutdown"); } - co_return std::make_optional(std::move(res.body())); + auto [data, errors] = client::parseServiceResponse(response::parseJSON(res.body())); + + co_return std::make_shared( + std::make_shared(std::move(data), std::move(errors))); }(m_host.c_str(), m_port.c_str(), m_target.c_str(), m_version, std::move(requestBody)), net::use_future); @@ -179,14 +282,25 @@ int main(int argc, char** argv) auto variables = serializeVariables( { input, ((argc > 1) ? std::make_optional(argv[1]) : std::nullopt) }); auto launch = service::await_async { std::make_shared() }; + auto state = std::make_shared(); auto serviceResponse = client::parseServiceResponse( - service->resolve({ query, GetOperationName(), std::move(variables), launch }).get()); + service->resolve({ query, GetOperationName(), std::move(variables), launch, state }) + .get()); auto result = client::query::relayQuery::parseResponse(std::move(serviceResponse.data)); auto errors = std::move(serviceResponse.errors); - if (result.relay) + if (result.relay.data) + { + std::cout << "Data: " << *result.relay.data << std::endl; + } + + if (result.relay.errors) { - std::cout << *result.relay << std::endl; + for (const auto& message : *result.relay.errors) + { + std::cerr << "Remote Error: " + << (message ? std::string_view { *message } : ""sv) << std::endl; + } } if (!errors.empty()) diff --git a/samples/proxy/query/ProxyClient.cpp b/samples/proxy/query/ProxyClient.cpp index 6124a0ac..30ae06e1 100644 --- a/samples/proxy/query/ProxyClient.cpp +++ b/samples/proxy/query/ProxyClient.cpp @@ -26,7 +26,10 @@ const std::string& GetRequestText() noexcept # Licensed under the MIT License. query relayQuery($query: String!, $operationName: String, $variables: String) { - relay(query: $query, operationName: $operationName, variables: $variables) + relay(query: $query, operationName: $operationName, variables: $variables) { + data + errors + } } )gql"s; @@ -51,6 +54,33 @@ const peg::ast& GetRequestObject() noexcept using namespace proxy; +template <> +query::relayQuery::Response::relay_Results Response::parse(response::Value&& response) +{ + query::relayQuery::Response::relay_Results result; + + if (response.type() == response::Type::Map) + { + auto members = response.release(); + + for (auto& member : members) + { + if (member.first == R"js(data)js"sv) + { + result.data = ModifiedResponse::parse(std::move(member.second)); + continue; + } + if (member.first == R"js(errors)js"sv) + { + result.errors = ModifiedResponse::parse(std::move(member.second)); + continue; + } + } + } + + return result; +} + namespace query::relayQuery { const std::string& GetOperationName() noexcept @@ -83,7 +113,7 @@ Response parseResponse(response::Value&& response) { if (member.first == R"js(relay)js"sv) { - result.relay = ModifiedResponse::parse(std::move(member.second)); + result.relay = ModifiedResponse::parse(std::move(member.second)); continue; } } diff --git a/samples/proxy/query/ProxyClient.h b/samples/proxy/query/ProxyClient.h index a1464f21..a2878c2f 100644 --- a/samples/proxy/query/ProxyClient.h +++ b/samples/proxy/query/ProxyClient.h @@ -32,7 +32,10 @@ namespace graphql::client { /// # Licensed under the MIT License. /// /// query relayQuery($query: String!, $operationName: String, $variables: String) { -/// relay(query: $query, operationName: $operationName, variables: $variables) +/// relay(query: $query, operationName: $operationName, variables: $variables) { +/// data +/// errors +/// } /// } /// namespace proxy { @@ -64,7 +67,13 @@ struct [[nodiscard("unnecessary construction")]] Variables struct [[nodiscard("unnecessary construction")]] Response { - std::optional relay {}; + struct [[nodiscard("unnecessary construction")]] relay_Results + { + std::optional data {}; + std::optional>> errors {}; + }; + + relay_Results relay {}; }; [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); diff --git a/samples/proxy/query/query.graphql b/samples/proxy/query/query.graphql index 9d75a165..54ca8e60 100644 --- a/samples/proxy/query/query.graphql +++ b/samples/proxy/query/query.graphql @@ -2,5 +2,8 @@ # Licensed under the MIT License. query relayQuery($query: String!, $operationName: String, $variables: String) { - relay(query: $query, operationName: $operationName, variables: $variables) + relay(query: $query, operationName: $operationName, variables: $variables) { + data + errors + } } diff --git a/samples/proxy/schema/ProxySchema.cpp b/samples/proxy/schema/ProxySchema.cpp index 0a6dc2f9..a4ef637d 100644 --- a/samples/proxy/schema/ProxySchema.cpp +++ b/samples/proxy/schema/ProxySchema.cpp @@ -35,8 +35,11 @@ void AddTypesToSchema(const std::shared_ptr& schema) { auto typeQuery = schema::ObjectType::Make(R"gql(Query)gql"sv, R"md()md"sv); schema->AddType(R"gql(Query)gql"sv, typeQuery); + auto typeResults = schema::ObjectType::Make(R"gql(Results)gql"sv, R"md()md"sv); + schema->AddType(R"gql(Results)gql"sv, typeResults); AddQueryDetails(typeQuery, schema); + AddResultsDetails(typeResults, schema); schema->AddQueryType(typeQuery); } diff --git a/samples/proxy/schema/ProxySchema.h b/samples/proxy/schema/ProxySchema.h index 77eca72d..9d4e544d 100644 --- a/samples/proxy/schema/ProxySchema.h +++ b/samples/proxy/schema/ProxySchema.h @@ -28,6 +28,7 @@ namespace proxy { namespace object { class Query; +class Results; } // namespace object @@ -50,6 +51,7 @@ class [[nodiscard("unnecessary construction")]] Operations final }; void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema); +void AddResultsDetails(const std::shared_ptr& typeResults, const std::shared_ptr& schema); std::shared_ptr GetSchema(); diff --git a/samples/proxy/schema/ProxySchema.ixx b/samples/proxy/schema/ProxySchema.ixx index 274f6963..c0b1b5b2 100644 --- a/samples/proxy/schema/ProxySchema.ixx +++ b/samples/proxy/schema/ProxySchema.ixx @@ -10,12 +10,14 @@ module; export module GraphQL.Proxy.ProxySchema; export import GraphQL.Proxy.QueryObject; +export import GraphQL.Proxy.ResultsObject; export namespace graphql::proxy { using proxy::Operations; using proxy::AddQueryDetails; +using proxy::AddResultsDetails; using proxy::GetSchema; diff --git a/samples/proxy/schema/QueryObject.cpp b/samples/proxy/schema/QueryObject.cpp index b07fe96c..d4dfb635 100644 --- a/samples/proxy/schema/QueryObject.cpp +++ b/samples/proxy/schema/QueryObject.cpp @@ -4,6 +4,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. #include "QueryObject.h" +#include "ResultsObject.h" #include "graphqlservice/internal/Introspection.h" @@ -65,7 +66,7 @@ service::AwaitableResolver Query::resolveRelay(service::ResolverParams&& params) auto result = _pimpl->getRelay(service::FieldParams { std::move(selectionSetParams), std::move(directives) }, std::move(argQuery), std::move(argOperationName), std::move(argVariables)); resolverLock.unlock(); - return service::ModifiedResult::convert(std::move(result), std::move(params)); + return service::ModifiedResult::convert(std::move(result), std::move(params)); } service::AwaitableResolver Query::resolve_typename(service::ResolverParams&& params) const @@ -92,7 +93,7 @@ service::AwaitableResolver Query::resolve_type(service::ResolverParams&& params) void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) { typeQuery->AddFields({ - schema::Field::Make(R"gql(relay)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv), { + schema::Field::Make(R"gql(relay)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(Results)gql"sv)), { schema::InputValue::Make(R"gql(query)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(String)gql"sv)), R"gql()gql"sv), schema::InputValue::Make(R"gql(operationName)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql()gql"sv), schema::InputValue::Make(R"gql(variables)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql()gql"sv) diff --git a/samples/proxy/schema/QueryObject.h b/samples/proxy/schema/QueryObject.h index f8973f09..0afd51de 100644 --- a/samples/proxy/schema/QueryObject.h +++ b/samples/proxy/schema/QueryObject.h @@ -16,13 +16,13 @@ namespace methods::QueryHas { template concept getRelayWithParams = requires (TImpl impl, service::FieldParams params, std::string queryArg, std::optional operationNameArg, std::optional variablesArg) { - { service::AwaitableScalar> { impl.getRelay(std::move(params), std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) } }; + { service::AwaitableObject> { impl.getRelay(std::move(params), std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) } }; }; template concept getRelay = requires (TImpl impl, std::string queryArg, std::optional operationNameArg, std::optional variablesArg) { - { service::AwaitableScalar> { impl.getRelay(std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) } }; + { service::AwaitableObject> { impl.getRelay(std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) } }; }; template @@ -58,7 +58,7 @@ class [[nodiscard("unnecessary construction")]] Query final virtual void beginSelectionSet(const service::SelectionSetParams& params) const = 0; virtual void endSelectionSet(const service::SelectionSetParams& params) const = 0; - [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar> getRelay(service::FieldParams&& params, std::string&& queryArg, std::optional&& operationNameArg, std::optional&& variablesArg) const = 0; + [[nodiscard("unnecessary call")]] virtual service::AwaitableObject> getRelay(service::FieldParams&& params, std::string&& queryArg, std::optional&& operationNameArg, std::optional&& variablesArg) const = 0; }; template @@ -70,7 +70,7 @@ class [[nodiscard("unnecessary construction")]] Query final { } - [[nodiscard("unnecessary call")]] service::AwaitableScalar> getRelay(service::FieldParams&& params, std::string&& queryArg, std::optional&& operationNameArg, std::optional&& variablesArg) const override + [[nodiscard("unnecessary call")]] service::AwaitableObject> getRelay(service::FieldParams&& params, std::string&& queryArg, std::optional&& operationNameArg, std::optional&& variablesArg) const override { if constexpr (methods::QueryHas::getRelayWithParams) { diff --git a/samples/proxy/schema/ResultsObject.cpp b/samples/proxy/schema/ResultsObject.cpp new file mode 100644 index 00000000..444f4b81 --- /dev/null +++ b/samples/proxy/schema/ResultsObject.cpp @@ -0,0 +1,91 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#include "ResultsObject.h" + +#include "graphqlservice/internal/Schema.h" + +#include "graphqlservice/introspection/IntrospectionSchema.h" + +#include +#include +#include +#include + +using namespace std::literals; + +namespace graphql::proxy { +namespace object { + +Results::Results(std::unique_ptr pimpl) noexcept + : service::Object{ getTypeNames(), getResolvers() } + , _pimpl { std::move(pimpl) } +{ +} + +service::TypeNames Results::getTypeNames() const noexcept +{ + return { + R"gql(Results)gql"sv + }; +} + +service::ResolverMap Results::getResolvers() const noexcept +{ + return { + { R"gql(data)gql"sv, [this](service::ResolverParams&& params) { return resolveData(std::move(params)); } }, + { R"gql(errors)gql"sv, [this](service::ResolverParams&& params) { return resolveErrors(std::move(params)); } }, + { R"gql(__typename)gql"sv, [this](service::ResolverParams&& params) { return resolve_typename(std::move(params)); } } + }; +} + +void Results::beginSelectionSet(const service::SelectionSetParams& params) const +{ + _pimpl->beginSelectionSet(params); +} + +void Results::endSelectionSet(const service::SelectionSetParams& params) const +{ + _pimpl->endSelectionSet(params); +} + +service::AwaitableResolver Results::resolveData(service::ResolverParams&& params) const +{ + std::unique_lock resolverLock(_resolverMutex); + service::SelectionSetParams selectionSetParams { static_cast(params) }; + auto directives = std::move(params.fieldDirectives); + auto result = _pimpl->getData(service::FieldParams { std::move(selectionSetParams), std::move(directives) }); + resolverLock.unlock(); + + return service::ModifiedResult::convert(std::move(result), std::move(params)); +} + +service::AwaitableResolver Results::resolveErrors(service::ResolverParams&& params) const +{ + std::unique_lock resolverLock(_resolverMutex); + service::SelectionSetParams selectionSetParams { static_cast(params) }; + auto directives = std::move(params.fieldDirectives); + auto result = _pimpl->getErrors(service::FieldParams { std::move(selectionSetParams), std::move(directives) }); + resolverLock.unlock(); + + return service::ModifiedResult::convert(std::move(result), std::move(params)); +} + +service::AwaitableResolver Results::resolve_typename(service::ResolverParams&& params) const +{ + return service::Result::convert(std::string{ R"gql(Results)gql" }, std::move(params)); +} + +} // namespace object + +void AddResultsDetails(const std::shared_ptr& typeResults, const std::shared_ptr& schema) +{ + typeResults->AddFields({ + schema::Field::Make(R"gql(data)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv)), + schema::Field::Make(R"gql(errors)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::LIST, schema->LookupType(R"gql(String)gql"sv))) + }); +} + +} // namespace graphql::proxy diff --git a/samples/proxy/schema/ResultsObject.h b/samples/proxy/schema/ResultsObject.h new file mode 100644 index 00000000..51718f38 --- /dev/null +++ b/samples/proxy/schema/ResultsObject.h @@ -0,0 +1,154 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef RESULTSOBJECT_H +#define RESULTSOBJECT_H + +#include "ProxySchema.h" + +namespace graphql::proxy::object { +namespace methods::ResultsHas { + +template +concept getDataWithParams = requires (TImpl impl, service::FieldParams params) +{ + { service::AwaitableScalar> { impl.getData(std::move(params)) } }; +}; + +template +concept getData = requires (TImpl impl) +{ + { service::AwaitableScalar> { impl.getData() } }; +}; + +template +concept getErrorsWithParams = requires (TImpl impl, service::FieldParams params) +{ + { service::AwaitableScalar>>> { impl.getErrors(std::move(params)) } }; +}; + +template +concept getErrors = requires (TImpl impl) +{ + { service::AwaitableScalar>>> { impl.getErrors() } }; +}; + +template +concept beginSelectionSet = requires (TImpl impl, const service::SelectionSetParams params) +{ + { impl.beginSelectionSet(params) }; +}; + +template +concept endSelectionSet = requires (TImpl impl, const service::SelectionSetParams params) +{ + { impl.endSelectionSet(params) }; +}; + +} // namespace methods::ResultsHas + +class [[nodiscard("unnecessary construction")]] Results final + : public service::Object +{ +private: + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveData(service::ResolverParams&& params) const; + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveErrors(service::ResolverParams&& params) const; + + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolve_typename(service::ResolverParams&& params) const; + + struct [[nodiscard("unnecessary construction")]] Concept + { + virtual ~Concept() = default; + + virtual void beginSelectionSet(const service::SelectionSetParams& params) const = 0; + virtual void endSelectionSet(const service::SelectionSetParams& params) const = 0; + + [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar> getData(service::FieldParams&& params) const = 0; + [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar>>> getErrors(service::FieldParams&& params) const = 0; + }; + + template + struct [[nodiscard("unnecessary construction")]] Model final + : Concept + { + explicit Model(std::shared_ptr pimpl) noexcept + : _pimpl { std::move(pimpl) } + { + } + + [[nodiscard("unnecessary call")]] service::AwaitableScalar> getData(service::FieldParams&& params) const override + { + if constexpr (methods::ResultsHas::getDataWithParams) + { + return { _pimpl->getData(std::move(params)) }; + } + else + { + static_assert(methods::ResultsHas::getData, R"msg(Results::getData is not implemented)msg"); + return { _pimpl->getData() }; + } + } + + [[nodiscard("unnecessary call")]] service::AwaitableScalar>>> getErrors(service::FieldParams&& params) const override + { + if constexpr (methods::ResultsHas::getErrorsWithParams) + { + return { _pimpl->getErrors(std::move(params)) }; + } + else + { + static_assert(methods::ResultsHas::getErrors, R"msg(Results::getErrors is not implemented)msg"); + return { _pimpl->getErrors() }; + } + } + + void beginSelectionSet(const service::SelectionSetParams& params) const override + { + if constexpr (methods::ResultsHas::beginSelectionSet) + { + _pimpl->beginSelectionSet(params); + } + } + + void endSelectionSet(const service::SelectionSetParams& params) const override + { + if constexpr (methods::ResultsHas::endSelectionSet) + { + _pimpl->endSelectionSet(params); + } + } + + private: + const std::shared_ptr _pimpl; + }; + + explicit Results(std::unique_ptr pimpl) noexcept; + + [[nodiscard("unnecessary call")]] service::TypeNames getTypeNames() const noexcept; + [[nodiscard("unnecessary call")]] service::ResolverMap getResolvers() const noexcept; + + void beginSelectionSet(const service::SelectionSetParams& params) const override; + void endSelectionSet(const service::SelectionSetParams& params) const override; + + const std::unique_ptr _pimpl; + +public: + template + explicit Results(std::shared_ptr pimpl) noexcept + : Results { std::unique_ptr { std::make_unique>(std::move(pimpl)) } } + { + } + + [[nodiscard("unnecessary call")]] static constexpr std::string_view getObjectType() noexcept + { + return { R"gql(Results)gql" }; + } +}; + +} // namespace graphql::proxy::object + +#endif // RESULTSOBJECT_H diff --git a/samples/proxy/schema/ResultsObject.ixx b/samples/proxy/schema/ResultsObject.ixx new file mode 100644 index 00000000..7f451cc6 --- /dev/null +++ b/samples/proxy/schema/ResultsObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ResultsObject.h" + +export module GraphQL.Proxy.ResultsObject; + +export namespace graphql::proxy::object { + +using object::Results; + +} // namespace graphql::proxy::object diff --git a/samples/proxy/schema/proxy_schema_files b/samples/proxy/schema/proxy_schema_files index dc325096..b2805af2 100644 --- a/samples/proxy/schema/proxy_schema_files +++ b/samples/proxy/schema/proxy_schema_files @@ -1,2 +1,3 @@ ProxySchema.cpp QueryObject.cpp +ResultsObject.cpp diff --git a/samples/proxy/schema/schema.graphql b/samples/proxy/schema/schema.graphql index 197569ae..fd32b986 100644 --- a/samples/proxy/schema/schema.graphql +++ b/samples/proxy/schema/schema.graphql @@ -2,5 +2,10 @@ # Licensed under the MIT License. type Query { - relay(query: String!, operationName: String, variables: String): String + relay(query: String!, operationName: String, variables: String): Results! +} + +type Results { + data: String + errors: [String] } From e216334e4543d00ca5300a5e7a9abbed4df0b0e0 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 19 Sep 2024 11:31:32 -0700 Subject: [PATCH 074/123] feat(sharetypes): rearrange namespaces so they can overlap --- samples/client/benchmark.cpp | 2 +- samples/client/benchmark/BenchmarkClient.cpp | 41 ++-- samples/client/benchmark/BenchmarkClient.h | 21 +-- samples/client/benchmark/BenchmarkClient.ixx | 17 +- .../client/multiple/MultipleQueriesClient.cpp | 148 +++++++++------ .../client/multiple/MultipleQueriesClient.h | 45 ++--- .../client/multiple/MultipleQueriesClient.ixx | 41 ++-- samples/client/mutate/MutateClient.cpp | 35 ++-- samples/client/mutate/MutateClient.h | 27 +-- samples/client/mutate/MutateClient.ixx | 23 ++- .../client/nestedinput/NestedInputClient.cpp | 35 ++-- .../client/nestedinput/NestedInputClient.h | 31 +-- .../client/nestedinput/NestedInputClient.ixx | 27 +-- samples/client/query/QueryClient.cpp | 72 +++---- samples/client/query/QueryClient.h | 25 +-- samples/client/query/QueryClient.ixx | 21 ++- samples/client/subscribe/SubscribeClient.cpp | 23 ++- samples/client/subscribe/SubscribeClient.h | 21 +-- samples/client/subscribe/SubscribeClient.ixx | 17 +- samples/proxy/client.cpp | 5 +- samples/proxy/query/ProxyClient.cpp | 25 ++- samples/proxy/query/ProxyClient.h | 21 +-- samples/proxy/query/ProxyClient.ixx | 17 +- src/ClientGenerator.cpp | 178 +++++++++++++----- test/ClientTests.cpp | 8 +- 25 files changed, 558 insertions(+), 368 deletions(-) diff --git a/samples/client/benchmark.cpp b/samples/client/benchmark.cpp index 73ce8780..bd699ea8 100644 --- a/samples/client/benchmark.cpp +++ b/samples/client/benchmark.cpp @@ -93,7 +93,7 @@ int main(int argc, char** argv) try { - using namespace client::query::Query; + using namespace benchmark::client::query::Query; auto query = GetRequestObject(); const auto& name = GetOperationName(); diff --git a/samples/client/benchmark/BenchmarkClient.cpp b/samples/client/benchmark/BenchmarkClient.cpp index 5a7e346b..0f9fb48b 100644 --- a/samples/client/benchmark/BenchmarkClient.cpp +++ b/samples/client/benchmark/BenchmarkClient.cpp @@ -16,8 +16,9 @@ using namespace std::literals; -namespace graphql::client { +namespace graphql { namespace benchmark { +namespace client { const std::string& GetRequestText() noexcept { @@ -59,14 +60,16 @@ const peg::ast& GetRequestObject() noexcept return s_request; } +} // namespace client } // namespace benchmark +namespace client { using namespace benchmark; template <> -query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo Response::parse(response::Value&& response) +graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo Response::parse(response::Value&& response) { - query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo result; + graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo result; if (response.type() == response::Type::Map) { @@ -86,9 +89,9 @@ query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo Re } template <> -query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment Response::parse(response::Value&& response) +graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment Response::parse(response::Value&& response) { - query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result; + graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result; if (response.type() == response::Type::Map) { @@ -123,9 +126,9 @@ query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdg } template <> -query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge Response::parse(response::Value&& response) +graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge Response::parse(response::Value&& response) { - query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge result; + graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge result; if (response.type() == response::Type::Map) { @@ -135,7 +138,7 @@ query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdg { if (member.first == R"js(node)js"sv) { - result.node = ModifiedResponse::parse(std::move(member.second)); + result.node = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -145,9 +148,9 @@ query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdg } template <> -query::Query::Response::appointments_AppointmentConnection Response::parse(response::Value&& response) +graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection Response::parse(response::Value&& response) { - query::Query::Response::appointments_AppointmentConnection result; + graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection result; if (response.type() == response::Type::Map) { @@ -157,12 +160,12 @@ query::Query::Response::appointments_AppointmentConnection Response::parse(std::move(member.second)); + result.pageInfo = ModifiedResponse::parse(std::move(member.second)); continue; } if (member.first == R"js(edges)js"sv) { - result.edges = ModifiedResponse::parse(std::move(member.second)); + result.edges = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -171,7 +174,9 @@ query::Query::Response::appointments_AppointmentConnection Response -/// Operation: query (unnamed) -/// -/// +/// # Operation: query (unnamed) +/// ```graphql /// # Copyright (c) Microsoft Corporation. All rights reserved. /// # Licensed under the MIT License. /// @@ -46,8 +44,8 @@ namespace graphql::client { /// } /// } /// } -/// -namespace benchmark { +/// ``` +namespace client { // Return the original text of the request document. [[nodiscard("unnecessary call")]] const std::string& GetRequestText() noexcept; @@ -55,12 +53,10 @@ namespace benchmark { // Return a pre-parsed, pre-validated request object. [[nodiscard("unnecessary call")]] const peg::ast& GetRequestObject() noexcept; -} // namespace benchmark - namespace query::Query { -using benchmark::GetRequestText; -using benchmark::GetRequestObject; +using graphql::benchmark::client::GetRequestText; +using graphql::benchmark::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; @@ -108,6 +104,7 @@ struct Traits }; } // namespace query::Query -} // namespace graphql::client +} // namespace client +} // namespace graphql::benchmark #endif // BENCHMARKCLIENT_H diff --git a/samples/client/benchmark/BenchmarkClient.ixx b/samples/client/benchmark/BenchmarkClient.ixx index 0400cf83..4ab91474 100644 --- a/samples/client/benchmark/BenchmarkClient.ixx +++ b/samples/client/benchmark/BenchmarkClient.ixx @@ -9,19 +9,17 @@ module; export module GraphQL.Benchmark.BenchmarkClient; -export namespace graphql::client { +export namespace graphql::benchmark { -namespace benchmark { +namespace client { -using benchmark::GetRequestText; -using benchmark::GetRequestObject; - -} // namespace benchmark +using client::GetRequestText; +using client::GetRequestObject; namespace query::Query { -using benchmark::GetRequestText; -using benchmark::GetRequestObject; +using graphql::benchmark::client::GetRequestText; +using graphql::benchmark::client::GetRequestObject; using Query::GetOperationName; using Query::Response; @@ -31,4 +29,5 @@ using Query::Traits; } // namespace query::Query -} // namespace graphql::client +} // namespace client +} // namespace graphql::benchmark diff --git a/samples/client/multiple/MultipleQueriesClient.cpp b/samples/client/multiple/MultipleQueriesClient.cpp index 3b5d533f..92959f11 100644 --- a/samples/client/multiple/MultipleQueriesClient.cpp +++ b/samples/client/multiple/MultipleQueriesClient.cpp @@ -16,8 +16,9 @@ using namespace std::literals; -namespace graphql::client { +namespace graphql { namespace multiple { +namespace client { const std::string& GetRequestText() noexcept { @@ -121,6 +122,10 @@ const peg::ast& GetRequestObject() noexcept return s_request; } +} // namespace client + +using namespace graphql::client; + CompleteTaskInput::CompleteTaskInput() noexcept : id {} , testTaskState {} @@ -179,13 +184,14 @@ CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexc } } // namespace multiple +namespace client { using namespace multiple; template <> -query::Appointments::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment Response::parse(response::Value&& response) +graphql::multiple::client::query::Appointments::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment Response::parse(response::Value&& response) { - query::Appointments::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result; + graphql::multiple::client::query::Appointments::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result; if (response.type() == response::Type::Map) { @@ -225,9 +231,9 @@ query::Appointments::Response::appointments_AppointmentConnection::edges_Appoint } template <> -query::Appointments::Response::appointments_AppointmentConnection::edges_AppointmentEdge Response::parse(response::Value&& response) +graphql::multiple::client::query::Appointments::Response::appointments_AppointmentConnection::edges_AppointmentEdge Response::parse(response::Value&& response) { - query::Appointments::Response::appointments_AppointmentConnection::edges_AppointmentEdge result; + graphql::multiple::client::query::Appointments::Response::appointments_AppointmentConnection::edges_AppointmentEdge result; if (response.type() == response::Type::Map) { @@ -237,7 +243,7 @@ query::Appointments::Response::appointments_AppointmentConnection::edges_Appoint { if (member.first == R"js(node)js"sv) { - result.node = ModifiedResponse::parse(std::move(member.second)); + result.node = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -247,9 +253,9 @@ query::Appointments::Response::appointments_AppointmentConnection::edges_Appoint } template <> -query::Appointments::Response::appointments_AppointmentConnection Response::parse(response::Value&& response) +graphql::multiple::client::query::Appointments::Response::appointments_AppointmentConnection Response::parse(response::Value&& response) { - query::Appointments::Response::appointments_AppointmentConnection result; + graphql::multiple::client::query::Appointments::Response::appointments_AppointmentConnection result; if (response.type() == response::Type::Map) { @@ -259,7 +265,7 @@ query::Appointments::Response::appointments_AppointmentConnection Response::parse(std::move(member.second)); + result.edges = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -268,7 +274,9 @@ query::Appointments::Response::appointments_AppointmentConnection Response -query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge::node_Task Response::parse(response::Value&& response) +graphql::multiple::client::query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge::node_Task Response::parse(response::Value&& response) { - query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge::node_Task result; + graphql::multiple::client::query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge::node_Task result; if (response.type() == response::Type::Map) { @@ -358,9 +371,9 @@ query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge::node_Task Response } template <> -query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge Response::parse(response::Value&& response) +graphql::multiple::client::query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge Response::parse(response::Value&& response) { - query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge result; + graphql::multiple::client::query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge result; if (response.type() == response::Type::Map) { @@ -370,7 +383,7 @@ query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge Response::parse(std::move(member.second)); + result.node = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -380,9 +393,9 @@ query::Tasks::Response::tasks_TaskConnection::edges_TaskEdge Response -query::Tasks::Response::tasks_TaskConnection Response::parse(response::Value&& response) +graphql::multiple::client::query::Tasks::Response::tasks_TaskConnection Response::parse(response::Value&& response) { - query::Tasks::Response::tasks_TaskConnection result; + graphql::multiple::client::query::Tasks::Response::tasks_TaskConnection result; if (response.type() == response::Type::Map) { @@ -392,7 +405,7 @@ query::Tasks::Response::tasks_TaskConnection Response::parse(std::move(member.second)); + result.edges = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -401,7 +414,9 @@ query::Tasks::Response::tasks_TaskConnection Response -query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge::node_Folder Response::parse(response::Value&& response) +graphql::multiple::client::query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge::node_Folder Response::parse(response::Value&& response) { - query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge::node_Folder result; + graphql::multiple::client::query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge::node_Folder result; if (response.type() == response::Type::Map) { @@ -491,9 +511,9 @@ query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge:: } template <> -query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge Response::parse(response::Value&& response) +graphql::multiple::client::query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge Response::parse(response::Value&& response) { - query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge result; + graphql::multiple::client::query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge result; if (response.type() == response::Type::Map) { @@ -503,7 +523,7 @@ query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge R { if (member.first == R"js(node)js"sv) { - result.node = ModifiedResponse::parse(std::move(member.second)); + result.node = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -513,9 +533,9 @@ query::UnreadCounts::Response::unreadCounts_FolderConnection::edges_FolderEdge R } template <> -query::UnreadCounts::Response::unreadCounts_FolderConnection Response::parse(response::Value&& response) +graphql::multiple::client::query::UnreadCounts::Response::unreadCounts_FolderConnection Response::parse(response::Value&& response) { - query::UnreadCounts::Response::unreadCounts_FolderConnection result; + graphql::multiple::client::query::UnreadCounts::Response::unreadCounts_FolderConnection result; if (response.type() == response::Type::Map) { @@ -525,7 +545,7 @@ query::UnreadCounts::Response::unreadCounts_FolderConnection Response::parse(std::move(member.second)); + result.edges = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -534,7 +554,9 @@ query::UnreadCounts::Response::unreadCounts_FolderConnection Response TaskState Response::parse(response::Value&& value) @@ -614,9 +642,9 @@ TaskState Response::parse(response::Value&& value) } template <> -query::Miscellaneous::Response::anyType_UnionType Response::parse(response::Value&& response) +graphql::multiple::client::query::Miscellaneous::Response::anyType_UnionType Response::parse(response::Value&& response) { - query::Miscellaneous::Response::anyType_UnionType result; + graphql::multiple::client::query::Miscellaneous::Response::anyType_UnionType result; if (response.type() == response::Type::Map) { @@ -665,7 +693,9 @@ query::Miscellaneous::Response::anyType_UnionType Response response::Value Variable::serialize(TaskState&& value) @@ -758,9 +794,9 @@ response::Value Variable::serialize(CompleteTaskInput&& input } template <> -mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task Response::parse(response::Value&& response) +graphql::multiple::client::mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task Response::parse(response::Value&& response) { - mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task result; + graphql::multiple::client::mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task result; if (response.type() == response::Type::Map) { @@ -790,9 +826,9 @@ mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::com } template <> -mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload Response::parse(response::Value&& response) +graphql::multiple::client::mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload Response::parse(response::Value&& response) { - mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload result; + graphql::multiple::client::mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload result; if (response.type() == response::Type::Map) { @@ -802,7 +838,7 @@ mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload Resp { if (member.first == R"js(completedTask)js"sv) { - result.completedTask = ModifiedResponse::parse(std::move(member.second)); + result.completedTask = ModifiedResponse::parse(std::move(member.second)); continue; } if (member.first == R"js(clientMutationId)js"sv) @@ -816,7 +852,9 @@ mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload Resp return result; } -namespace mutation::CompleteTaskMutation { +} // namespace client + +namespace multiple::client::mutation::CompleteTaskMutation { const std::string& GetOperationName() noexcept { @@ -827,6 +865,8 @@ const std::string& GetOperationName() noexcept response::Value serializeVariables(Variables&& variables) { + using namespace graphql::client; + response::Value result { response::Type::Map }; result.emplace_back(R"js(input)js"s, ModifiedVariable::serialize(std::move(variables.input))); @@ -837,6 +877,8 @@ response::Value serializeVariables(Variables&& variables) Response parseResponse(response::Value&& response) { + using namespace graphql::client; + Response result; if (response.type() == response::Type::Map) @@ -858,12 +900,12 @@ Response parseResponse(response::Value&& response) [[nodiscard("unnecessary call")]] const std::string& Traits::GetRequestText() noexcept { - return multiple::GetRequestText(); + return client::GetRequestText(); } [[nodiscard("unnecessary call")]] const peg::ast& Traits::GetRequestObject() noexcept { - return multiple::GetRequestObject(); + return client::GetRequestObject(); } [[nodiscard("unnecessary call")]] const std::string& Traits::GetOperationName() noexcept @@ -881,5 +923,5 @@ Response parseResponse(response::Value&& response) return CompleteTaskMutation::parseResponse(std::move(response)); } -} // namespace mutation::CompleteTaskMutation -} // namespace graphql::client +} // namespace multiple::client::mutation::CompleteTaskMutation +} // namespace graphql diff --git a/samples/client/multiple/MultipleQueriesClient.h b/samples/client/multiple/MultipleQueriesClient.h index 4e3e7634..8806bec7 100644 --- a/samples/client/multiple/MultipleQueriesClient.h +++ b/samples/client/multiple/MultipleQueriesClient.h @@ -22,12 +22,10 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); -namespace graphql::client { +namespace graphql::multiple { -/// -/// Operations: query Appointments, query Tasks, query UnreadCounts, query Miscellaneous, mutation CompleteTaskMutation -/// -/// +/// # Operations: query Appointments, query Tasks, query UnreadCounts, query Miscellaneous, mutation CompleteTaskMutation +/// ```graphql /// # Copyright (c) Microsoft Corporation. All rights reserved. /// # Licensed under the MIT License. /// @@ -108,8 +106,8 @@ namespace graphql::client { /// clientMutationId @skip(if: $skipClientMutationId) /// } /// } -/// -namespace multiple { +/// ``` +namespace client { // Return the original text of the request document. [[nodiscard("unnecessary call")]] const std::string& GetRequestText() noexcept; @@ -117,6 +115,8 @@ namespace multiple { // Return a pre-parsed, pre-validated request object. [[nodiscard("unnecessary call")]] const peg::ast& GetRequestObject() noexcept; +} // namespace client + enum class [[nodiscard("unnecessary conversion")]] TaskState { Unassigned, @@ -146,12 +146,12 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput std::optional clientMutationId; }; -} // namespace multiple +namespace client { namespace query::Appointments { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using graphql::multiple::client::GetRequestText; +using graphql::multiple::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; @@ -197,8 +197,8 @@ struct Traits namespace query::Tasks { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using graphql::multiple::client::GetRequestText; +using graphql::multiple::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; @@ -243,8 +243,8 @@ struct Traits namespace query::UnreadCounts { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using graphql::multiple::client::GetRequestText; +using graphql::multiple::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; @@ -289,13 +289,13 @@ struct Traits namespace query::Miscellaneous { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using graphql::multiple::client::GetRequestText; +using graphql::multiple::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; -using multiple::TaskState; +using graphql::multiple::TaskState; struct [[nodiscard("unnecessary construction")]] Response { @@ -332,15 +332,15 @@ struct Traits namespace mutation::CompleteTaskMutation { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using graphql::multiple::client::GetRequestText; +using graphql::multiple::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; -using multiple::TaskState; +using graphql::multiple::TaskState; -using multiple::CompleteTaskInput; +using graphql::multiple::CompleteTaskInput; struct [[nodiscard("unnecessary construction")]] Variables { @@ -386,6 +386,7 @@ struct Traits }; } // namespace mutation::CompleteTaskMutation -} // namespace graphql::client +} // namespace client +} // namespace graphql::multiple #endif // MULTIPLEQUERIESCLIENT_H diff --git a/samples/client/multiple/MultipleQueriesClient.ixx b/samples/client/multiple/MultipleQueriesClient.ixx index a12ea9b4..d21f7130 100644 --- a/samples/client/multiple/MultipleQueriesClient.ixx +++ b/samples/client/multiple/MultipleQueriesClient.ixx @@ -9,23 +9,25 @@ module; export module GraphQL.MultipleQueries.MultipleQueriesClient; -export namespace graphql::client { +export namespace graphql::multiple { -namespace multiple { +namespace client { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using client::GetRequestText; +using client::GetRequestObject; + +} // namespace client using multiple::TaskState; using multiple::CompleteTaskInput; -} // namespace multiple +namespace client { namespace query::Appointments { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using graphql::multiple::client::GetRequestText; +using graphql::multiple::client::GetRequestObject; using Appointments::GetOperationName; using Appointments::Response; @@ -37,8 +39,8 @@ using Appointments::Traits; namespace query::Tasks { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using graphql::multiple::client::GetRequestText; +using graphql::multiple::client::GetRequestObject; using Tasks::GetOperationName; using Tasks::Response; @@ -50,8 +52,8 @@ using Tasks::Traits; namespace query::UnreadCounts { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using graphql::multiple::client::GetRequestText; +using graphql::multiple::client::GetRequestObject; using UnreadCounts::GetOperationName; using UnreadCounts::Response; @@ -63,11 +65,11 @@ using UnreadCounts::Traits; namespace query::Miscellaneous { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using graphql::multiple::client::GetRequestText; +using graphql::multiple::client::GetRequestObject; using Miscellaneous::GetOperationName; -using multiple::TaskState; +using graphql::multiple::TaskState; using Miscellaneous::Response; using Miscellaneous::parseResponse; @@ -78,13 +80,13 @@ using Miscellaneous::Traits; namespace mutation::CompleteTaskMutation { -using multiple::GetRequestText; -using multiple::GetRequestObject; +using graphql::multiple::client::GetRequestText; +using graphql::multiple::client::GetRequestObject; using CompleteTaskMutation::GetOperationName; -using multiple::TaskState; +using graphql::multiple::TaskState; -using multiple::CompleteTaskInput; +using graphql::multiple::CompleteTaskInput; using CompleteTaskMutation::Variables; using CompleteTaskMutation::serializeVariables; @@ -96,4 +98,5 @@ using CompleteTaskMutation::Traits; } // namespace mutation::CompleteTaskMutation -} // namespace graphql::client +} // namespace client +} // namespace graphql::multiple diff --git a/samples/client/mutate/MutateClient.cpp b/samples/client/mutate/MutateClient.cpp index 8db8bd6a..a0f26f85 100644 --- a/samples/client/mutate/MutateClient.cpp +++ b/samples/client/mutate/MutateClient.cpp @@ -16,8 +16,9 @@ using namespace std::literals; -namespace graphql::client { +namespace graphql { namespace mutate { +namespace client { const std::string& GetRequestText() noexcept { @@ -54,6 +55,10 @@ const peg::ast& GetRequestObject() noexcept return s_request; } +} // namespace client + +using namespace graphql::client; + CompleteTaskInput::CompleteTaskInput() noexcept : id {} , testTaskState {} @@ -113,6 +118,8 @@ CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexc } // namespace mutate +namespace client { + using namespace mutate; template <> @@ -173,9 +180,9 @@ TaskState Response::parse(response::Value&& value) } template <> -mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task Response::parse(response::Value&& response) +graphql::mutate::client::mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task Response::parse(response::Value&& response) { - mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task result; + graphql::mutate::client::mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::completedTask_Task result; if (response.type() == response::Type::Map) { @@ -205,9 +212,9 @@ mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload::com } template <> -mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload Response::parse(response::Value&& response) +graphql::mutate::client::mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload Response::parse(response::Value&& response) { - mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload result; + graphql::mutate::client::mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload result; if (response.type() == response::Type::Map) { @@ -217,7 +224,7 @@ mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload Resp { if (member.first == R"js(completedTask)js"sv) { - result.completedTask = ModifiedResponse::parse(std::move(member.second)); + result.completedTask = ModifiedResponse::parse(std::move(member.second)); continue; } if (member.first == R"js(clientMutationId)js"sv) @@ -231,7 +238,9 @@ mutation::CompleteTaskMutation::Response::completedTask_CompleteTaskPayload Resp return result; } -namespace mutation::CompleteTaskMutation { +} // namespace client + +namespace mutate::client::mutation::CompleteTaskMutation { const std::string& GetOperationName() noexcept { @@ -242,6 +251,8 @@ const std::string& GetOperationName() noexcept response::Value serializeVariables(Variables&& variables) { + using namespace graphql::client; + response::Value result { response::Type::Map }; result.emplace_back(R"js(input)js"s, ModifiedVariable::serialize(std::move(variables.input))); @@ -252,6 +263,8 @@ response::Value serializeVariables(Variables&& variables) Response parseResponse(response::Value&& response) { + using namespace graphql::client; + Response result; if (response.type() == response::Type::Map) @@ -273,12 +286,12 @@ Response parseResponse(response::Value&& response) [[nodiscard("unnecessary call")]] const std::string& Traits::GetRequestText() noexcept { - return mutate::GetRequestText(); + return client::GetRequestText(); } [[nodiscard("unnecessary call")]] const peg::ast& Traits::GetRequestObject() noexcept { - return mutate::GetRequestObject(); + return client::GetRequestObject(); } [[nodiscard("unnecessary call")]] const std::string& Traits::GetOperationName() noexcept @@ -296,5 +309,5 @@ Response parseResponse(response::Value&& response) return CompleteTaskMutation::parseResponse(std::move(response)); } -} // namespace mutation::CompleteTaskMutation -} // namespace graphql::client +} // namespace mutate::client::mutation::CompleteTaskMutation +} // namespace graphql diff --git a/samples/client/mutate/MutateClient.h b/samples/client/mutate/MutateClient.h index 74870657..ab016aaa 100644 --- a/samples/client/mutate/MutateClient.h +++ b/samples/client/mutate/MutateClient.h @@ -22,12 +22,10 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); -namespace graphql::client { +namespace graphql::mutate { -/// -/// Operation: mutation CompleteTaskMutation -/// -/// +/// # Operation: mutation CompleteTaskMutation +/// ```graphql /// # Copyright (c) Microsoft Corporation. All rights reserved. /// # Licensed under the MIT License. /// @@ -41,8 +39,8 @@ namespace graphql::client { /// clientMutationId @skip(if: $skipClientMutationId) /// } /// } -/// -namespace mutate { +/// ``` +namespace client { // Return the original text of the request document. [[nodiscard("unnecessary call")]] const std::string& GetRequestText() noexcept; @@ -50,6 +48,8 @@ namespace mutate { // Return a pre-parsed, pre-validated request object. [[nodiscard("unnecessary call")]] const peg::ast& GetRequestObject() noexcept; +} // namespace client + enum class [[nodiscard("unnecessary conversion")]] TaskState { Unassigned, @@ -79,19 +79,19 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput std::optional clientMutationId; }; -} // namespace mutate +namespace client { namespace mutation::CompleteTaskMutation { -using mutate::GetRequestText; -using mutate::GetRequestObject; +using graphql::mutate::client::GetRequestText; +using graphql::mutate::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; -using mutate::TaskState; +using graphql::mutate::TaskState; -using mutate::CompleteTaskInput; +using graphql::mutate::CompleteTaskInput; struct [[nodiscard("unnecessary construction")]] Variables { @@ -137,6 +137,7 @@ struct Traits }; } // namespace mutation::CompleteTaskMutation -} // namespace graphql::client +} // namespace client +} // namespace graphql::mutate #endif // MUTATECLIENT_H diff --git a/samples/client/mutate/MutateClient.ixx b/samples/client/mutate/MutateClient.ixx index 67b20b6d..4e781529 100644 --- a/samples/client/mutate/MutateClient.ixx +++ b/samples/client/mutate/MutateClient.ixx @@ -9,28 +9,30 @@ module; export module GraphQL.Mutate.MutateClient; -export namespace graphql::client { +export namespace graphql::mutate { -namespace mutate { +namespace client { -using mutate::GetRequestText; -using mutate::GetRequestObject; +using client::GetRequestText; +using client::GetRequestObject; + +} // namespace client using mutate::TaskState; using mutate::CompleteTaskInput; -} // namespace mutate +namespace client { namespace mutation::CompleteTaskMutation { -using mutate::GetRequestText; -using mutate::GetRequestObject; +using graphql::mutate::client::GetRequestText; +using graphql::mutate::client::GetRequestObject; using CompleteTaskMutation::GetOperationName; -using mutate::TaskState; +using graphql::mutate::TaskState; -using mutate::CompleteTaskInput; +using graphql::mutate::CompleteTaskInput; using CompleteTaskMutation::Variables; using CompleteTaskMutation::serializeVariables; @@ -42,4 +44,5 @@ using CompleteTaskMutation::Traits; } // namespace mutation::CompleteTaskMutation -} // namespace graphql::client +} // namespace client +} // namespace graphql::mutate diff --git a/samples/client/nestedinput/NestedInputClient.cpp b/samples/client/nestedinput/NestedInputClient.cpp index 8de48529..a70c79ba 100644 --- a/samples/client/nestedinput/NestedInputClient.cpp +++ b/samples/client/nestedinput/NestedInputClient.cpp @@ -16,8 +16,9 @@ using namespace std::literals; -namespace graphql::client { +namespace graphql { namespace nestedinput { +namespace client { const std::string& GetRequestText() noexcept { @@ -48,6 +49,10 @@ const peg::ast& GetRequestObject() noexcept return s_request; } +} // namespace client + +using namespace graphql::client; + InputA::InputA() noexcept : a {} { @@ -236,6 +241,8 @@ InputBC& InputBC::operator=(InputBC&& other) noexcept } // namespace nestedinput +namespace client { + using namespace nestedinput; template <> @@ -284,9 +291,9 @@ response::Value Variable::serialize(InputBC&& inputValue) } template <> -query::testQuery::Response::control_Control::test_Output Response::parse(response::Value&& response) +graphql::nestedinput::client::query::testQuery::Response::control_Control::test_Output Response::parse(response::Value&& response) { - query::testQuery::Response::control_Control::test_Output result; + graphql::nestedinput::client::query::testQuery::Response::control_Control::test_Output result; if (response.type() == response::Type::Map) { @@ -306,9 +313,9 @@ query::testQuery::Response::control_Control::test_Output Response -query::testQuery::Response::control_Control Response::parse(response::Value&& response) +graphql::nestedinput::client::query::testQuery::Response::control_Control Response::parse(response::Value&& response) { - query::testQuery::Response::control_Control result; + graphql::nestedinput::client::query::testQuery::Response::control_Control result; if (response.type() == response::Type::Map) { @@ -318,7 +325,7 @@ query::testQuery::Response::control_Control Response::parse(std::move(member.second)); + result.test = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -327,7 +334,9 @@ query::testQuery::Response::control_Control Response::serialize(std::move(variables.stream))); @@ -347,6 +358,8 @@ response::Value serializeVariables(Variables&& variables) Response parseResponse(response::Value&& response) { + using namespace graphql::client; + Response result; if (response.type() == response::Type::Map) @@ -368,12 +381,12 @@ Response parseResponse(response::Value&& response) [[nodiscard("unnecessary call")]] const std::string& Traits::GetRequestText() noexcept { - return nestedinput::GetRequestText(); + return client::GetRequestText(); } [[nodiscard("unnecessary call")]] const peg::ast& Traits::GetRequestObject() noexcept { - return nestedinput::GetRequestObject(); + return client::GetRequestObject(); } [[nodiscard("unnecessary call")]] const std::string& Traits::GetOperationName() noexcept @@ -391,5 +404,5 @@ Response parseResponse(response::Value&& response) return testQuery::parseResponse(std::move(response)); } -} // namespace query::testQuery -} // namespace graphql::client +} // namespace nestedinput::client::query::testQuery +} // namespace graphql diff --git a/samples/client/nestedinput/NestedInputClient.h b/samples/client/nestedinput/NestedInputClient.h index 8a1cf0eb..2350eb51 100644 --- a/samples/client/nestedinput/NestedInputClient.h +++ b/samples/client/nestedinput/NestedInputClient.h @@ -22,12 +22,10 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); -namespace graphql::client { +namespace graphql::nestedinput { -/// -/// Operation: query testQuery -/// -/// +/// # Operation: query testQuery +/// ```graphql /// query testQuery($stream: InputABCD!) { /// control { /// test(new: $stream) { @@ -35,8 +33,8 @@ namespace graphql::client { /// } /// } /// } -/// -namespace nestedinput { +/// ``` +namespace client { // Return the original text of the request document. [[nodiscard("unnecessary call")]] const std::string& GetRequestText() noexcept; @@ -44,6 +42,8 @@ namespace nestedinput { // Return a pre-parsed, pre-validated request object. [[nodiscard("unnecessary call")]] const peg::ast& GetRequestObject() noexcept; +} // namespace client + struct [[nodiscard("unnecessary construction")]] InputA { explicit InputA() noexcept; @@ -116,20 +116,20 @@ struct [[nodiscard("unnecessary construction")]] InputBC InputB b; }; -} // namespace nestedinput +namespace client { namespace query::testQuery { -using nestedinput::GetRequestText; -using nestedinput::GetRequestObject; +using graphql::nestedinput::client::GetRequestText; +using graphql::nestedinput::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; -using nestedinput::InputA; -using nestedinput::InputB; -using nestedinput::InputABCD; -using nestedinput::InputBC; +using graphql::nestedinput::InputA; +using graphql::nestedinput::InputB; +using graphql::nestedinput::InputABCD; +using graphql::nestedinput::InputBC; struct [[nodiscard("unnecessary construction")]] Variables { @@ -171,6 +171,7 @@ struct Traits }; } // namespace query::testQuery -} // namespace graphql::client +} // namespace client +} // namespace graphql::nestedinput #endif // NESTEDINPUTCLIENT_H diff --git a/samples/client/nestedinput/NestedInputClient.ixx b/samples/client/nestedinput/NestedInputClient.ixx index c7f1253b..71430abe 100644 --- a/samples/client/nestedinput/NestedInputClient.ixx +++ b/samples/client/nestedinput/NestedInputClient.ixx @@ -9,30 +9,32 @@ module; export module GraphQL.NestedInput.NestedInputClient; -export namespace graphql::client { +export namespace graphql::nestedinput { -namespace nestedinput { +namespace client { -using nestedinput::GetRequestText; -using nestedinput::GetRequestObject; +using client::GetRequestText; +using client::GetRequestObject; + +} // namespace client using nestedinput::InputA; using nestedinput::InputB; using nestedinput::InputABCD; using nestedinput::InputBC; -} // namespace nestedinput +namespace client { namespace query::testQuery { -using nestedinput::GetRequestText; -using nestedinput::GetRequestObject; +using graphql::nestedinput::client::GetRequestText; +using graphql::nestedinput::client::GetRequestObject; using testQuery::GetOperationName; -using nestedinput::InputA; -using nestedinput::InputB; -using nestedinput::InputABCD; -using nestedinput::InputBC; +using graphql::nestedinput::InputA; +using graphql::nestedinput::InputB; +using graphql::nestedinput::InputABCD; +using graphql::nestedinput::InputBC; using testQuery::Variables; using testQuery::serializeVariables; @@ -44,4 +46,5 @@ using testQuery::Traits; } // namespace query::testQuery -} // namespace graphql::client +} // namespace client +} // namespace graphql::nestedinput diff --git a/samples/client/query/QueryClient.cpp b/samples/client/query/QueryClient.cpp index 0e874d20..46f381f0 100644 --- a/samples/client/query/QueryClient.cpp +++ b/samples/client/query/QueryClient.cpp @@ -16,8 +16,9 @@ using namespace std::literals; -namespace graphql::client { +namespace graphql { namespace query { +namespace client { const std::string& GetRequestText() noexcept { @@ -102,8 +103,11 @@ const peg::ast& GetRequestObject() noexcept return s_request; } +} // namespace client } // namespace query +namespace client { + using namespace query; template <> @@ -134,9 +138,9 @@ TaskState Response::parse(response::Value&& value) } template <> -query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment Response::parse(response::Value&& response) +graphql::query::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment Response::parse(response::Value&& response) { - query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result; + graphql::query::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result; if (response.type() == response::Type::Map) { @@ -176,9 +180,9 @@ query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdg } template <> -query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge Response::parse(response::Value&& response) +graphql::query::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge Response::parse(response::Value&& response) { - query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge result; + graphql::query::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge result; if (response.type() == response::Type::Map) { @@ -188,7 +192,7 @@ query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdg { if (member.first == R"js(node)js"sv) { - result.node = ModifiedResponse::parse(std::move(member.second)); + result.node = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -198,9 +202,9 @@ query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdg } template <> -query::Query::Response::appointments_AppointmentConnection Response::parse(response::Value&& response) +graphql::query::client::query::Query::Response::appointments_AppointmentConnection Response::parse(response::Value&& response) { - query::Query::Response::appointments_AppointmentConnection result; + graphql::query::client::query::Query::Response::appointments_AppointmentConnection result; if (response.type() == response::Type::Map) { @@ -210,7 +214,7 @@ query::Query::Response::appointments_AppointmentConnection Response::parse(std::move(member.second)); + result.edges = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -220,9 +224,9 @@ query::Query::Response::appointments_AppointmentConnection Response -query::Query::Response::tasks_TaskConnection::edges_TaskEdge::node_Task Response::parse(response::Value&& response) +graphql::query::client::query::Query::Response::tasks_TaskConnection::edges_TaskEdge::node_Task Response::parse(response::Value&& response) { - query::Query::Response::tasks_TaskConnection::edges_TaskEdge::node_Task result; + graphql::query::client::query::Query::Response::tasks_TaskConnection::edges_TaskEdge::node_Task result; if (response.type() == response::Type::Map) { @@ -257,9 +261,9 @@ query::Query::Response::tasks_TaskConnection::edges_TaskEdge::node_Task Response } template <> -query::Query::Response::tasks_TaskConnection::edges_TaskEdge Response::parse(response::Value&& response) +graphql::query::client::query::Query::Response::tasks_TaskConnection::edges_TaskEdge Response::parse(response::Value&& response) { - query::Query::Response::tasks_TaskConnection::edges_TaskEdge result; + graphql::query::client::query::Query::Response::tasks_TaskConnection::edges_TaskEdge result; if (response.type() == response::Type::Map) { @@ -269,7 +273,7 @@ query::Query::Response::tasks_TaskConnection::edges_TaskEdge Response::parse(std::move(member.second)); + result.node = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -279,9 +283,9 @@ query::Query::Response::tasks_TaskConnection::edges_TaskEdge Response -query::Query::Response::tasks_TaskConnection Response::parse(response::Value&& response) +graphql::query::client::query::Query::Response::tasks_TaskConnection Response::parse(response::Value&& response) { - query::Query::Response::tasks_TaskConnection result; + graphql::query::client::query::Query::Response::tasks_TaskConnection result; if (response.type() == response::Type::Map) { @@ -291,7 +295,7 @@ query::Query::Response::tasks_TaskConnection Response::parse(std::move(member.second)); + result.edges = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -301,9 +305,9 @@ query::Query::Response::tasks_TaskConnection Response -query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge::node_Folder Response::parse(response::Value&& response) +graphql::query::client::query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge::node_Folder Response::parse(response::Value&& response) { - query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge::node_Folder result; + graphql::query::client::query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge::node_Folder result; if (response.type() == response::Type::Map) { @@ -338,9 +342,9 @@ query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge::node_Fo } template <> -query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge Response::parse(response::Value&& response) +graphql::query::client::query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge Response::parse(response::Value&& response) { - query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge result; + graphql::query::client::query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge result; if (response.type() == response::Type::Map) { @@ -350,7 +354,7 @@ query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge Response { if (member.first == R"js(node)js"sv) { - result.node = ModifiedResponse::parse(std::move(member.second)); + result.node = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -360,9 +364,9 @@ query::Query::Response::unreadCounts_FolderConnection::edges_FolderEdge Response } template <> -query::Query::Response::unreadCounts_FolderConnection Response::parse(response::Value&& response) +graphql::query::client::query::Query::Response::unreadCounts_FolderConnection Response::parse(response::Value&& response) { - query::Query::Response::unreadCounts_FolderConnection result; + graphql::query::client::query::Query::Response::unreadCounts_FolderConnection result; if (response.type() == response::Type::Map) { @@ -372,7 +376,7 @@ query::Query::Response::unreadCounts_FolderConnection Response::parse(std::move(member.second)); + result.edges = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -382,9 +386,9 @@ query::Query::Response::unreadCounts_FolderConnection Response -query::Query::Response::anyType_UnionType Response::parse(response::Value&& response) +graphql::query::client::query::Query::Response::anyType_UnionType Response::parse(response::Value&& response) { - query::Query::Response::anyType_UnionType result; + graphql::query::client::query::Query::Response::anyType_UnionType result; if (response.type() == response::Type::Map) { @@ -433,7 +437,9 @@ query::Query::Response::anyType_UnionType Response -/// Operation: query (unnamed) -/// -/// +/// # Operation: query (unnamed) +/// ```graphql /// # Copyright (c) Microsoft Corporation. All rights reserved. /// # Licensed under the MIT License. /// @@ -89,8 +87,8 @@ namespace graphql::client { /// # Try a field with a C++ keyword /// default /// } -/// -namespace query { +/// ``` +namespace client { // Return the original text of the request document. [[nodiscard("unnecessary call")]] const std::string& GetRequestText() noexcept; @@ -98,6 +96,8 @@ namespace query { // Return a pre-parsed, pre-validated request object. [[nodiscard("unnecessary call")]] const peg::ast& GetRequestObject() noexcept; +} // namespace client + enum class [[nodiscard("unnecessary conversion")]] TaskState { Unassigned, @@ -106,17 +106,17 @@ enum class [[nodiscard("unnecessary conversion")]] TaskState Complete, }; -} // namespace query +namespace client { namespace query::Query { -using query::GetRequestText; -using query::GetRequestObject; +using graphql::query::client::GetRequestText; +using graphql::query::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; -using query::TaskState; +using graphql::query::TaskState; struct [[nodiscard("unnecessary construction")]] Response { @@ -208,6 +208,7 @@ struct Traits }; } // namespace query::Query -} // namespace graphql::client +} // namespace client +} // namespace graphql::query #endif // QUERYCLIENT_H diff --git a/samples/client/query/QueryClient.ixx b/samples/client/query/QueryClient.ixx index 97f91145..7d59ccdf 100644 --- a/samples/client/query/QueryClient.ixx +++ b/samples/client/query/QueryClient.ixx @@ -9,24 +9,26 @@ module; export module GraphQL.Query.QueryClient; -export namespace graphql::client { +export namespace graphql::query { -namespace query { +namespace client { -using query::GetRequestText; -using query::GetRequestObject; +using client::GetRequestText; +using client::GetRequestObject; + +} // namespace client using query::TaskState; -} // namespace query +namespace client { namespace query::Query { -using query::GetRequestText; -using query::GetRequestObject; +using graphql::query::client::GetRequestText; +using graphql::query::client::GetRequestObject; using Query::GetOperationName; -using query::TaskState; +using graphql::query::TaskState; using Query::Response; using Query::parseResponse; @@ -35,4 +37,5 @@ using Query::Traits; } // namespace query::Query -} // namespace graphql::client +} // namespace client +} // namespace graphql::query diff --git a/samples/client/subscribe/SubscribeClient.cpp b/samples/client/subscribe/SubscribeClient.cpp index ea516d6c..3945722a 100644 --- a/samples/client/subscribe/SubscribeClient.cpp +++ b/samples/client/subscribe/SubscribeClient.cpp @@ -16,8 +16,9 @@ using namespace std::literals; -namespace graphql::client { +namespace graphql { namespace subscribe { +namespace client { const std::string& GetRequestText() noexcept { @@ -52,14 +53,16 @@ const peg::ast& GetRequestObject() noexcept return s_request; } +} // namespace client } // namespace subscribe +namespace client { using namespace subscribe; template <> -subscription::TestSubscription::Response::nextAppointment_Appointment Response::parse(response::Value&& response) +graphql::subscribe::client::subscription::TestSubscription::Response::nextAppointment_Appointment Response::parse(response::Value&& response) { - subscription::TestSubscription::Response::nextAppointment_Appointment result; + graphql::subscribe::client::subscription::TestSubscription::Response::nextAppointment_Appointment result; if (response.type() == response::Type::Map) { @@ -93,7 +96,9 @@ subscription::TestSubscription::Response::nextAppointment_Appointment Response -/// Operation: subscription TestSubscription -/// -/// +/// # Operation: subscription TestSubscription +/// ```graphql /// # Copyright (c) Microsoft Corporation. All rights reserved. /// # Licensed under the MIT License. /// @@ -39,8 +37,8 @@ namespace graphql::client { /// isNow /// } /// } -/// -namespace subscribe { +/// ``` +namespace client { // Return the original text of the request document. [[nodiscard("unnecessary call")]] const std::string& GetRequestText() noexcept; @@ -48,12 +46,10 @@ namespace subscribe { // Return a pre-parsed, pre-validated request object. [[nodiscard("unnecessary call")]] const peg::ast& GetRequestObject() noexcept; -} // namespace subscribe - namespace subscription::TestSubscription { -using subscribe::GetRequestText; -using subscribe::GetRequestObject; +using graphql::subscribe::client::GetRequestText; +using graphql::subscribe::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; @@ -85,6 +81,7 @@ struct Traits }; } // namespace subscription::TestSubscription -} // namespace graphql::client +} // namespace client +} // namespace graphql::subscribe #endif // SUBSCRIBECLIENT_H diff --git a/samples/client/subscribe/SubscribeClient.ixx b/samples/client/subscribe/SubscribeClient.ixx index cf92a734..13456256 100644 --- a/samples/client/subscribe/SubscribeClient.ixx +++ b/samples/client/subscribe/SubscribeClient.ixx @@ -9,19 +9,17 @@ module; export module GraphQL.Subscribe.SubscribeClient; -export namespace graphql::client { +export namespace graphql::subscribe { -namespace subscribe { +namespace client { -using subscribe::GetRequestText; -using subscribe::GetRequestObject; - -} // namespace subscribe +using client::GetRequestText; +using client::GetRequestObject; namespace subscription::TestSubscription { -using subscribe::GetRequestText; -using subscribe::GetRequestObject; +using graphql::subscribe::client::GetRequestText; +using graphql::subscribe::client::GetRequestObject; using TestSubscription::GetOperationName; using TestSubscription::Response; @@ -31,4 +29,5 @@ using TestSubscription::Traits; } // namespace subscription::TestSubscription -} // namespace graphql::client +} // namespace client +} // namespace graphql::subscribe diff --git a/samples/proxy/client.cpp b/samples/proxy/client.cpp index 61893e72..2fbddc43 100644 --- a/samples/proxy/client.cpp +++ b/samples/proxy/client.cpp @@ -276,7 +276,7 @@ int main(int argc, char** argv) std::cout << "Executing query..." << std::endl; - using namespace client::query::relayQuery; + using namespace proxy::client::query::relayQuery; auto query = GetRequestObject(); auto variables = serializeVariables( @@ -286,7 +286,8 @@ int main(int argc, char** argv) auto serviceResponse = client::parseServiceResponse( service->resolve({ query, GetOperationName(), std::move(variables), launch, state }) .get()); - auto result = client::query::relayQuery::parseResponse(std::move(serviceResponse.data)); + auto result = + proxy::client::query::relayQuery::parseResponse(std::move(serviceResponse.data)); auto errors = std::move(serviceResponse.errors); if (result.relay.data) diff --git a/samples/proxy/query/ProxyClient.cpp b/samples/proxy/query/ProxyClient.cpp index 30ae06e1..6a9aecc8 100644 --- a/samples/proxy/query/ProxyClient.cpp +++ b/samples/proxy/query/ProxyClient.cpp @@ -16,8 +16,9 @@ using namespace std::literals; -namespace graphql::client { +namespace graphql { namespace proxy { +namespace client { const std::string& GetRequestText() noexcept { @@ -50,14 +51,16 @@ const peg::ast& GetRequestObject() noexcept return s_request; } +} // namespace client } // namespace proxy +namespace client { using namespace proxy; template <> -query::relayQuery::Response::relay_Results Response::parse(response::Value&& response) +graphql::proxy::client::query::relayQuery::Response::relay_Results Response::parse(response::Value&& response) { - query::relayQuery::Response::relay_Results result; + graphql::proxy::client::query::relayQuery::Response::relay_Results result; if (response.type() == response::Type::Map) { @@ -81,7 +84,9 @@ query::relayQuery::Response::relay_Results Response::serialize(std::move(variables.query))); @@ -103,6 +110,8 @@ response::Value serializeVariables(Variables&& variables) Response parseResponse(response::Value&& response) { + using namespace graphql::client; + Response result; if (response.type() == response::Type::Map) @@ -124,12 +133,12 @@ Response parseResponse(response::Value&& response) [[nodiscard("unnecessary call")]] const std::string& Traits::GetRequestText() noexcept { - return proxy::GetRequestText(); + return client::GetRequestText(); } [[nodiscard("unnecessary call")]] const peg::ast& Traits::GetRequestObject() noexcept { - return proxy::GetRequestObject(); + return client::GetRequestObject(); } [[nodiscard("unnecessary call")]] const std::string& Traits::GetOperationName() noexcept @@ -147,5 +156,5 @@ Response parseResponse(response::Value&& response) return relayQuery::parseResponse(std::move(response)); } -} // namespace query::relayQuery -} // namespace graphql::client +} // namespace proxy::client::query::relayQuery +} // namespace graphql diff --git a/samples/proxy/query/ProxyClient.h b/samples/proxy/query/ProxyClient.h index a2878c2f..90e75ad0 100644 --- a/samples/proxy/query/ProxyClient.h +++ b/samples/proxy/query/ProxyClient.h @@ -22,12 +22,10 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); -namespace graphql::client { +namespace graphql::proxy { -/// -/// Operation: query relayQuery -/// -/// +/// # Operation: query relayQuery +/// ```graphql /// # Copyright (c) Microsoft Corporation. All rights reserved. /// # Licensed under the MIT License. /// @@ -37,8 +35,8 @@ namespace graphql::client { /// errors /// } /// } -/// -namespace proxy { +/// ``` +namespace client { // Return the original text of the request document. [[nodiscard("unnecessary call")]] const std::string& GetRequestText() noexcept; @@ -46,12 +44,10 @@ namespace proxy { // Return a pre-parsed, pre-validated request object. [[nodiscard("unnecessary call")]] const peg::ast& GetRequestObject() noexcept; -} // namespace proxy - namespace query::relayQuery { -using proxy::GetRequestText; -using proxy::GetRequestObject; +using graphql::proxy::client::GetRequestText; +using graphql::proxy::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; @@ -94,6 +90,7 @@ struct Traits }; } // namespace query::relayQuery -} // namespace graphql::client +} // namespace client +} // namespace graphql::proxy #endif // PROXYCLIENT_H diff --git a/samples/proxy/query/ProxyClient.ixx b/samples/proxy/query/ProxyClient.ixx index e74294c1..8151c844 100644 --- a/samples/proxy/query/ProxyClient.ixx +++ b/samples/proxy/query/ProxyClient.ixx @@ -9,19 +9,17 @@ module; export module GraphQL.Proxy.ProxyClient; -export namespace graphql::client { +export namespace graphql::proxy { -namespace proxy { +namespace client { -using proxy::GetRequestText; -using proxy::GetRequestObject; - -} // namespace proxy +using client::GetRequestText; +using client::GetRequestObject; namespace query::relayQuery { -using proxy::GetRequestText; -using proxy::GetRequestObject; +using graphql::proxy::client::GetRequestText; +using graphql::proxy::client::GetRequestObject; using relayQuery::GetOperationName; using relayQuery::Variables; @@ -34,4 +32,5 @@ using relayQuery::Traits; } // namespace query::relayQuery -} // namespace graphql::client +} // namespace client +} // namespace graphql::proxy diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 8af33dff..f8be81e8 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -99,7 +99,7 @@ std::string Generator::getSourcePath() const noexcept const std::string& Generator::getClientNamespace() const noexcept { - static const auto s_namespace = R"cpp(graphql::client)cpp"s; + static const auto s_namespace = R"cpp(client)cpp"s; return s_namespace; } @@ -209,12 +209,13 @@ static_assert(graphql::internal::MinorVersion == )cpp" )cpp"; - PendingBlankLine pendingSeparator { headerFile }; - NamespaceScope clientNamespaceScope { headerFile, getClientNamespace() }; + const auto schemaNamespace = std::format("graphql::{}", _schemaLoader.getSchemaNamespace()); + NamespaceScope schemaNamespaceScope { headerFile, schemaNamespace }; outputRequestComment(headerFile); - NamespaceScope schemaNamespaceScope { headerFile, _schemaLoader.getSchemaNamespace() }; + NamespaceScope clientNamespaceScope { headerFile, getClientNamespace() }; + PendingBlankLine pendingSeparator { headerFile }; outputGetRequestDeclaration(headerFile); @@ -235,6 +236,11 @@ static_assert(graphql::internal::MinorVersion == )cpp" pendingSeparator.reset(); + if (clientNamespaceScope.exit()) + { + headerFile << std::endl; + } + headerFile << R"cpp(enum class [[nodiscard("unnecessary conversion")]] )cpp" << cppType << R"cpp( { @@ -270,6 +276,11 @@ static_assert(graphql::internal::MinorVersion == )cpp" pendingSeparator.reset(); + if (clientNamespaceScope.exit()) + { + headerFile << std::endl; + } + if (!inputType.declarations.empty()) { // Forward declare nullable dependencies @@ -348,8 +359,10 @@ static_assert(graphql::internal::MinorVersion == )cpp" } pendingSeparator.reset(); - schemaNamespaceScope.exit(); - pendingSeparator.add(); + if (clientNamespaceScope.enter()) + { + pendingSeparator.add(); + } for (const auto& operation : operations) { @@ -358,9 +371,11 @@ static_assert(graphql::internal::MinorVersion == )cpp" NamespaceScope operationNamespaceScope { headerFile, getOperationNamespace(operation) }; headerFile << R"cpp( -using )cpp" << _schemaLoader.getSchemaNamespace() +using graphql::)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << getClientNamespace() << R"cpp(::GetRequestText; -using )cpp" << _schemaLoader.getSchemaNamespace() +using graphql::)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << getClientNamespace() << R"cpp(::GetRequestObject; )cpp"; @@ -369,8 +384,8 @@ using )cpp" << _schemaLoader.getSchemaNamespace() // Alias all of the enums referenced either in variables or the response. for (const auto& enumType : _requestLoader.getReferencedEnums(operation)) { - headerFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" - << _schemaLoader.getCppType(enumType->name()) << R"cpp(; + headerFile << R"cpp(using graphql::)cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::)cpp" << _schemaLoader.getCppType(enumType->name()) << R"cpp(; )cpp"; pendingSeparator.add(); @@ -381,8 +396,9 @@ using )cpp" << _schemaLoader.getSchemaNamespace() // Alias all of the input object structs referenced in variables. for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) { - headerFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" - << _schemaLoader.getCppType(inputType.type->name()) << R"cpp(; + headerFile << R"cpp(using graphql::)cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::)cpp" << _schemaLoader.getCppType(inputType.type->name()) + << R"cpp(; )cpp"; pendingSeparator.add(); @@ -484,8 +500,7 @@ struct Traits void Generator::outputRequestComment(std::ostream& headerFile) const noexcept { headerFile << R"cpp( -/// -/// Operation)cpp"; +/// # Operation)cpp"; const auto& operations = _requestLoader.getOperations(); @@ -512,8 +527,7 @@ void Generator::outputRequestComment(std::ostream& headerFile) const noexcept } headerFile << R"cpp( -/// -/// +/// ```graphql )cpp"; std::istringstream request { std::string { _requestLoader.getRequestText() } }; @@ -523,7 +537,7 @@ void Generator::outputRequestComment(std::ostream& headerFile) const noexcept headerFile << R"cpp(/// )cpp" << line << std::endl; } - headerFile << R"cpp(/// + headerFile << R"cpp(/// ``` )cpp"; } @@ -640,17 +654,18 @@ export module GraphQL.)cpp" export )cpp"; - NamespaceScope graphqlNamespace { moduleFile, getClientNamespace() }; + const auto schemaNamespace = std::format("graphql::{}", _schemaLoader.getSchemaNamespace()); + NamespaceScope schemaNamespaceScope { moduleFile, schemaNamespace }; moduleFile << std::endl; - NamespaceScope schemaNamespace { moduleFile, _schemaLoader.getSchemaNamespace() }; + NamespaceScope clientNamespaceScope { moduleFile, getClientNamespace() }; PendingBlankLine pendingSeparator { moduleFile }; moduleFile << R"cpp( -using )cpp" << _schemaLoader.getSchemaNamespace() +using )cpp" << getClientNamespace() << R"cpp(::GetRequestText; -using )cpp" << _schemaLoader.getSchemaNamespace() +using )cpp" << getClientNamespace() << R"cpp(::GetRequestObject; )cpp"; @@ -663,6 +678,11 @@ using )cpp" << _schemaLoader.getSchemaNamespace() { pendingSeparator.reset(); + if (clientNamespaceScope.exit()) + { + moduleFile << std::endl; + } + // Define all of the enums referenced either in variables or the response. for (const auto& enumType : _requestLoader.getReferencedEnums(operation)) { @@ -694,6 +714,11 @@ using )cpp" << _schemaLoader.getSchemaNamespace() { pendingSeparator.reset(); + if (clientNamespaceScope.exit()) + { + moduleFile << std::endl; + } + // Define all of the input object structs referenced in variables. for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) { @@ -717,7 +742,7 @@ using )cpp" << _schemaLoader.getSchemaNamespace() } pendingSeparator.reset(); - if (schemaNamespace.exit()) + if (clientNamespaceScope.enter()) { pendingSeparator.add(); } @@ -730,9 +755,11 @@ using )cpp" << _schemaLoader.getSchemaNamespace() const auto operationNamespace = _requestLoader.getOperationNamespace(operation); moduleFile << R"cpp( -using )cpp" << _schemaLoader.getSchemaNamespace() +using graphql::)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << getClientNamespace() << R"cpp(::GetRequestText; -using )cpp" << _schemaLoader.getSchemaNamespace() +using graphql::)cpp" + << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" << getClientNamespace() << R"cpp(::GetRequestObject; using )cpp" << operationNamespace << R"cpp(::GetOperationName; @@ -742,8 +769,8 @@ using )cpp" << operationNamespace // Alias all of the enums referenced either in variables or the response. for (const auto& enumType : _requestLoader.getReferencedEnums(operation)) { - moduleFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" - << _schemaLoader.getCppType(enumType->name()) << R"cpp(; + moduleFile << R"cpp(using graphql::)cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::)cpp" << _schemaLoader.getCppType(enumType->name()) << R"cpp(; )cpp"; pendingSeparator.add(); @@ -754,8 +781,9 @@ using )cpp" << operationNamespace // Alias all of the input object structs referenced in variables. for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) { - moduleFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" - << _schemaLoader.getCppType(inputType.type->name()) << R"cpp(; + moduleFile << R"cpp(using graphql::)cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::)cpp" << _schemaLoader.getCppType(inputType.type->name()) + << R"cpp(; )cpp"; pendingSeparator.add(); @@ -819,8 +847,9 @@ using namespace std::literals; )cpp"; - NamespaceScope clientNamespaceScope { sourceFile, getClientNamespace() }; + NamespaceScope graphqlNamespaceScope { sourceFile, "graphql" }; NamespaceScope schemaNamespaceScope { sourceFile, _schemaLoader.getSchemaNamespace() }; + NamespaceScope clientNamespaceScope { sourceFile, getClientNamespace() }; PendingBlankLine pendingSeparator { sourceFile }; outputGetRequestImplementation(sourceFile); @@ -841,6 +870,15 @@ using namespace std::literals; pendingSeparator.reset(); + if (clientNamespaceScope.exit()) + { + sourceFile << R"cpp( +using namespace graphql::)cpp" + << getClientNamespace() << R"cpp(; + +)cpp"; + } + sourceFile << cppType << R"cpp(::)cpp" << cppType << R"cpp(() noexcept)cpp"; bool firstField = true; @@ -979,14 +1017,11 @@ using namespace std::literals; } pendingSeparator.reset(); - schemaNamespaceScope.exit(); - - sourceFile << R"cpp( -using namespace )cpp" - << _schemaLoader.getSchemaNamespace() << R"cpp(; -)cpp"; - - pendingSeparator.add(); + clientNamespaceScope.exit(); + if (schemaNamespaceScope.exit()) + { + pendingSeparator.add(); + } std::unordered_set outputModifiedVariableEnum; std::unordered_set outputModifiedVariableInput; @@ -1009,6 +1044,15 @@ using namespace )cpp" pendingSeparator.reset(); + if (clientNamespaceScope.enter()) + { + sourceFile << R"cpp( +using namespace )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(; + +)cpp"; + } + const auto& enumValues = enumType->enumValues(); sourceFile << R"cpp(template <> @@ -1058,10 +1102,18 @@ response::Value Variable<)cpp" pendingSeparator.reset(); + if (clientNamespaceScope.enter()) + { + sourceFile << R"cpp( +using namespace )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(; + +)cpp"; + } + sourceFile << R"cpp(template <> response::Value Variable<)cpp" - << cppType << R"cpp(>::serialize()cpp" << cppType - << R"cpp(&& inputValue) + << cppType << R"cpp(>::serialize()cpp" << cppType << R"cpp(&& inputValue) { response::Value result { response::Type::Map }; @@ -1101,6 +1153,15 @@ response::Value Variable<)cpp" pendingSeparator.reset(); + if (clientNamespaceScope.enter()) + { + sourceFile << R"cpp( +using namespace )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(; + +)cpp"; + } + const auto& enumValues = enumType->enumValues(); sourceFile << R"cpp(template <> @@ -1167,21 +1228,40 @@ response::Value Variable<)cpp" pendingSeparator.add(); } - const auto currentScope = - std::format(R"cpp({}::Response)cpp", getOperationNamespace(operation)); + const auto operationNamespace = std::format("{}::client::{}", + _schemaLoader.getSchemaNamespace(), + getOperationNamespace(operation)); + const auto graphqlCurrentScope = + std::format(R"cpp(graphql::{}::Response)cpp", operationNamespace); const auto& responseType = _requestLoader.getResponseType(operation); for (const auto& responseField : responseType.fields) { - if (outputModifiedResponseImplementation(sourceFile, currentScope, responseField)) + if (clientNamespaceScope.enter()) + { + sourceFile << R"cpp( +using namespace )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(; +)cpp"; + } + + if (outputModifiedResponseImplementation(sourceFile, + graphqlCurrentScope, + responseField)) { pendingSeparator.add(); } } pendingSeparator.reset(); + if (clientNamespaceScope.exit()) + { + sourceFile << std::endl; + } - NamespaceScope operationNamespaceScope { sourceFile, getOperationNamespace(operation) }; + NamespaceScope operationNamespaceScope { sourceFile, operationNamespace }; + const auto schemaCurrentScope = + std::format("{}::Response", getOperationNamespace(operation)); outputGetOperationNameImplementation(sourceFile, operation); @@ -1190,6 +1270,9 @@ response::Value Variable<)cpp" sourceFile << R"cpp( response::Value serializeVariables(Variables&& variables) { + using namespace graphql::)cpp" + << getClientNamespace() << R"cpp(; + response::Value result { response::Type::Map }; )cpp"; @@ -1213,6 +1296,9 @@ response::Value serializeVariables(Variables&& variables) sourceFile << R"cpp( Response parseResponse(response::Value&& response) { + using namespace graphql::)cpp" + << getClientNamespace() << R"cpp(; + Response result; if (response.type() == response::Type::Map) @@ -1234,7 +1320,7 @@ Response parseResponse(response::Value&& response) { result.)cpp" << responseField.cppName << R"cpp( = ModifiedResponse<)cpp" - << getResponseFieldCppType(responseField, currentScope) + << getResponseFieldCppType(responseField, schemaCurrentScope) << R"cpp(>::parse)cpp" << getTypeModifierList(responseField.modifiers) << R"cpp((std::move(member.second)); continue; @@ -1251,13 +1337,13 @@ Response parseResponse(response::Value&& response) [[nodiscard("unnecessary call")]] const std::string& Traits::GetRequestText() noexcept { - return )cpp" << _schemaLoader.getSchemaNamespace() + return )cpp" << getClientNamespace() << R"cpp(::GetRequestText(); } [[nodiscard("unnecessary call")]] const peg::ast& Traits::GetRequestObject() noexcept { - return )cpp" << _schemaLoader.getSchemaNamespace() + return )cpp" << getClientNamespace() << R"cpp(::GetRequestObject(); } diff --git a/test/ClientTests.cpp b/test/ClientTests.cpp index 5a576b66..031e4c47 100644 --- a/test/ClientTests.cpp +++ b/test/ClientTests.cpp @@ -40,7 +40,7 @@ class ClientCase : public ::testing::Test TEST_F(ClientCase, QueryEverything) { - using namespace client::query::Query; + using namespace query::client::query::Query; auto query = GetRequestObject(); @@ -114,7 +114,7 @@ TEST_F(ClientCase, QueryEverything) EXPECT_EQ(3, unreadCountNode->unreadCount) << "unreadCount should match"; EXPECT_EQ("Folder", unreadCountNode->_typename) << "__typename should match"; - EXPECT_EQ(client::query::Query::TaskState::Unassigned, response.testTaskState) + EXPECT_EQ(query::client::query::Query::TaskState::Unassigned, response.testTaskState) << "testTaskState should match"; ASSERT_EQ(std::size_t { 1 }, response.anyType.size()) << "anyType should have 1 entry"; @@ -139,7 +139,7 @@ TEST_F(ClientCase, QueryEverything) TEST_F(ClientCase, MutateCompleteTask) { - using namespace client::mutation::CompleteTaskMutation; + using namespace mutate::client::mutation::CompleteTaskMutation; auto query = GetRequestObject(); auto variables = serializeVariables( @@ -181,7 +181,7 @@ TEST_F(ClientCase, MutateCompleteTask) TEST_F(ClientCase, SubscribeNextAppointmentChangeDefault) { - using namespace client::subscription::TestSubscription; + using namespace subscribe::client::subscription::TestSubscription; auto query = GetRequestObject(); From 88ec4632170949ad3d29d9b676034b7c4b651c5b Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 19 Sep 2024 13:00:25 -0700 Subject: [PATCH 075/123] feat(sharetypes): reuse schema types in proxy client --- include/RequestLoader.h | 39 +- samples/proxy/client.cpp | 36 +- samples/proxy/query/CMakeLists.txt | 3 +- samples/proxy/query/ProxyClient.cpp | 70 +++- samples/proxy/query/ProxyClient.h | 18 +- samples/proxy/query/ProxyClient.ixx | 12 + samples/proxy/query/query.graphql | 4 +- samples/proxy/schema/ProxySchema.cpp | 160 +++++++- samples/proxy/schema/ProxySchema.h | 55 ++- samples/proxy/schema/ProxySchema.ixx | 10 +- samples/proxy/schema/QueryObject.cpp | 16 +- samples/proxy/schema/QueryObject.h | 16 +- ...sultsObject.cpp => QueryResultsObject.cpp} | 26 +- .../{ResultsObject.h => QueryResultsObject.h} | 32 +- ...sultsObject.ixx => QueryResultsObject.ixx} | 6 +- samples/proxy/schema/proxy_schema_files | 2 +- samples/proxy/schema/schema.graphql | 17 +- src/ClientGenerator.cpp | 367 ++++++++++-------- src/RequestLoader.cpp | 5 + 19 files changed, 608 insertions(+), 286 deletions(-) rename samples/proxy/schema/{ResultsObject.cpp => QueryResultsObject.cpp} (73%) rename samples/proxy/schema/{ResultsObject.h => QueryResultsObject.h} (80%) rename samples/proxy/schema/{ResultsObject.ixx => QueryResultsObject.ixx} (71%) diff --git a/include/RequestLoader.h b/include/RequestLoader.h index 8ec05d3c..96911e9b 100644 --- a/include/RequestLoader.h +++ b/include/RequestLoader.h @@ -84,6 +84,7 @@ struct [[nodiscard("unnecessary construction")]] RequestOptions const std::string requestFilename; const std::optional operationName; const bool noIntrospection = false; + const bool sharedTypes = false; }; class SchemaLoader; @@ -91,16 +92,16 @@ class SchemaLoader; class [[nodiscard("unnecessary construction")]] RequestLoader { public: - explicit RequestLoader(RequestOptions && requestOptions, const SchemaLoader& schemaLoader); + explicit RequestLoader(RequestOptions&& requestOptions, const SchemaLoader& schemaLoader); [[nodiscard("unnecessary call")]] std::string_view getRequestFilename() const noexcept; [[nodiscard("unnecessary call")]] const OperationList& getOperations() const noexcept; [[nodiscard("unnecessary call")]] std::string_view getOperationDisplayName( const Operation& operation) const noexcept; - [[nodiscard("unnecessary call")]] std::string getOperationNamespace(const Operation& operation) - const noexcept; - [[nodiscard("unnecessary call")]] std::string_view getOperationType(const Operation& operation) - const noexcept; + [[nodiscard("unnecessary call")]] std::string getOperationNamespace( + const Operation& operation) const noexcept; + [[nodiscard("unnecessary call")]] std::string_view getOperationType( + const Operation& operation) const noexcept; [[nodiscard("unnecessary call")]] std::string_view getRequestText() const noexcept; [[nodiscard("unnecessary call")]] const ResponseType& getResponseType( @@ -108,6 +109,7 @@ class [[nodiscard("unnecessary construction")]] RequestLoader [[nodiscard("unnecessary call")]] const RequestVariableList& getVariables( const Operation& operation) const noexcept; + [[nodiscard("unnecessary call")]] bool useSharedTypes() const noexcept; [[nodiscard("unnecessary call")]] const RequestInputTypeList& getReferencedInputTypes( const Operation& operation) const noexcept; [[nodiscard("unnecessary call")]] const RequestSchemaTypeList& getReferencedEnums( @@ -116,20 +118,18 @@ class [[nodiscard("unnecessary construction")]] RequestLoader [[nodiscard("unnecessary call")]] std::string getInputCppType( const RequestSchemaType& wrappedInputType) const noexcept; [[nodiscard("unnecessary call")]] std::string getInputCppType( - const RequestSchemaType& inputType, - const TypeModifierStack& modifiers) const noexcept; + const RequestSchemaType& inputType, const TypeModifierStack& modifiers) const noexcept; [[nodiscard("unnecessary call")]] static std::string getOutputCppType( - std::string_view outputCppType, - const TypeModifierStack& modifiers) noexcept; + std::string_view outputCppType, const TypeModifierStack& modifiers) noexcept; [[nodiscard("unnecessary call")]] static std::pair - unwrapSchemaType(RequestSchemaType && type) noexcept; + unwrapSchemaType(RequestSchemaType&& type) noexcept; private: void buildSchema(); void addTypesToSchema(); - [[nodiscard("unnecessary call")]] RequestSchemaType getSchemaType(std::string_view type, - const TypeModifierStack& modifiers) const noexcept; + [[nodiscard("unnecessary call")]] RequestSchemaType getSchemaType( + std::string_view type, const TypeModifierStack& modifiers) const noexcept; void validateRequest() const; [[nodiscard("unnecessary call")]] static std::string_view trimWhitespace( @@ -137,11 +137,11 @@ class [[nodiscard("unnecessary construction")]] RequestLoader void findOperation(); void collectFragments() noexcept; - void collectVariables(Operation & operation) noexcept; - void collectInputTypes(Operation & operation, const RequestSchemaType& variableType) noexcept; - void reorderInputTypeDependencies(Operation & operation); - void collectEnums(Operation & operation, const RequestSchemaType& variableType) noexcept; - void collectEnums(Operation & operation, const ResponseField& responseField) noexcept; + void collectVariables(Operation& operation) noexcept; + void collectInputTypes(Operation& operation, const RequestSchemaType& variableType) noexcept; + void reorderInputTypeDependencies(Operation& operation); + void collectEnums(Operation& operation, const RequestSchemaType& variableType) noexcept; + void collectEnums(Operation& operation, const ResponseField& responseField) noexcept; using FragmentDefinitionMap = std::map; @@ -150,8 +150,7 @@ class [[nodiscard("unnecessary construction")]] RequestLoader { public: explicit SelectionVisitor(const SchemaLoader& schemaLoader, - const FragmentDefinitionMap& fragments, - const std::shared_ptr& schema, + const FragmentDefinitionMap& fragments, const std::shared_ptr& schema, const RequestSchemaType& type); void visit(const peg::ast_node& selection); @@ -163,7 +162,7 @@ class [[nodiscard("unnecessary construction")]] RequestLoader void visitFragmentSpread(const peg::ast_node& fragmentSpread); void visitInlineFragment(const peg::ast_node& inlineFragment); - void mergeFragmentFields(ResponseFieldList && fragmentFields) noexcept; + void mergeFragmentFields(ResponseFieldList&& fragmentFields) noexcept; const SchemaLoader& _schemaLoader; const FragmentDefinitionMap& _fragments; diff --git a/samples/proxy/client.cpp b/samples/proxy/client.cpp index 2fbddc43..5b09b6f2 100644 --- a/samples/proxy/client.cpp +++ b/samples/proxy/client.cpp @@ -5,7 +5,7 @@ #include "schema/ProxySchema.h" #include "schema/QueryObject.h" -#include "schema/ResultsObject.h" +#include "schema/QueryResultsObject.h" #include "graphqlservice/JSONResponse.h" @@ -151,9 +151,8 @@ class Query explicit Query(std::string_view host, std::string_view port, std::string_view target, int version) noexcept; - std::future> getRelay(std::string&& queryArg, - std::optional&& operationNameArg, - std::optional&& variablesArg) const; + std::future> getRelay( + proxy::QueryInput&& inputArg) const; private: const std::string m_host; @@ -173,21 +172,22 @@ Query::Query( // Based on: // https://www.boost.org/doc/libs/1_82_0/libs/beast/example/http/client/awaitable/http_client_awaitable.cpp -std::future> Query::getRelay(std::string&& queryArg, - std::optional&& operationNameArg, std::optional&& variablesArg) const +std::future> Query::getRelay( + proxy::QueryInput&& inputArg) const { response::Value payload { response::Type::Map }; - payload.emplace_back("query"s, response::Value { std::move(queryArg) }); + payload.emplace_back("query"s, response::Value { std::move(inputArg.query) }); - if (operationNameArg) + if (inputArg.operationName) { - payload.emplace_back("operationName"s, response::Value { std::move(*operationNameArg) }); + payload.emplace_back("operationName"s, + response::Value { std::move(*inputArg.operationName) }); } - if (variablesArg) + if (inputArg.variables) { - payload.emplace_back("variables"s, response::Value { std::move(*variablesArg) }); + payload.emplace_back("variables"s, response::Value { std::move(*inputArg.variables) }); } std::string requestBody = response::toJSON(std::move(payload)); @@ -199,7 +199,8 @@ std::future> Query::getRelay(std::string const char* port, const char* target, int version, - std::string requestBody) -> net::awaitable> { + std::string requestBody) + -> net::awaitable> { // These objects perform our I/O. They use an executor with a default completion token // of use_awaitable. This makes our code easy, but will use exceptions as the default // error handling, i.e. if the connection drops, we might see an exception. @@ -252,7 +253,7 @@ std::future> Query::getRelay(std::string auto [data, errors] = client::parseServiceResponse(response::parseJSON(res.body())); - co_return std::make_shared( + co_return std::make_shared( std::make_shared(std::move(data), std::move(errors))); }(m_host.c_str(), m_port.c_str(), m_target.c_str(), m_version, std::move(requestBody)), net::use_future); @@ -279,15 +280,16 @@ int main(int argc, char** argv) using namespace proxy::client::query::relayQuery; auto query = GetRequestObject(); - auto variables = serializeVariables( - { input, ((argc > 1) ? std::make_optional(argv[1]) : std::nullopt) }); + auto variables = serializeVariables({ QueryInput { OperationType::QUERY, + input, + ((argc > 1) ? std::make_optional(argv[1]) : std::nullopt), + std::nullopt } }); auto launch = service::await_async { std::make_shared() }; auto state = std::make_shared(); auto serviceResponse = client::parseServiceResponse( service->resolve({ query, GetOperationName(), std::move(variables), launch, state }) .get()); - auto result = - proxy::client::query::relayQuery::parseResponse(std::move(serviceResponse.data)); + auto result = parseResponse(std::move(serviceResponse.data)); auto errors = std::move(serviceResponse.errors); if (result.relay.data) diff --git a/samples/proxy/query/CMakeLists.txt b/samples/proxy/query/CMakeLists.txt index 4c8e5e50..8c4fcdb0 100644 --- a/samples/proxy/query/CMakeLists.txt +++ b/samples/proxy/query/CMakeLists.txt @@ -7,7 +7,8 @@ cmake_minimum_required(VERSION 3.28) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) if(GRAPHQL_UPDATE_SAMPLES AND GRAPHQL_BUILD_CLIENTGEN) - update_graphql_client_files(proxy ../schema/schema.graphql query.graphql Proxy proxy) + update_graphql_client_files(proxy ../schema/schema.graphql query.graphql Proxy proxy --shared-types) endif() add_graphql_client_target(proxy) +target_link_libraries(proxy_client PRIVATE proxy_schema) \ No newline at end of file diff --git a/samples/proxy/query/ProxyClient.cpp b/samples/proxy/query/ProxyClient.cpp index 6a9aecc8..d40a39a9 100644 --- a/samples/proxy/query/ProxyClient.cpp +++ b/samples/proxy/query/ProxyClient.cpp @@ -26,8 +26,8 @@ const std::string& GetRequestText() noexcept # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. - query relayQuery($query: String!, $operationName: String, $variables: String) { - relay(query: $query, operationName: $operationName, variables: $variables) { + query relayQuery($input: QueryInput!) { + relay(input: $input) { data errors } @@ -53,14 +53,70 @@ const peg::ast& GetRequestObject() noexcept } // namespace client } // namespace proxy + namespace client { using namespace proxy; template <> -graphql::proxy::client::query::relayQuery::Response::relay_Results Response::parse(response::Value&& response) +response::Value Variable::serialize(OperationType&& value) +{ + static const std::array s_names = { + R"gql(QUERY)gql"sv, + R"gql(MUTATION)gql"sv, + R"gql(SUBSCRIPTION)gql"sv + }; + + response::Value result { response::Type::EnumValue }; + + result.set(std::string { s_names[static_cast(value)] }); + + return result; +} + +template <> +response::Value Variable::serialize(QueryInput&& inputValue) +{ + response::Value result { response::Type::Map }; + + result.emplace_back(R"js(type)js"s, ModifiedVariable::serialize(std::move(inputValue.type))); + result.emplace_back(R"js(query)js"s, ModifiedVariable::serialize(std::move(inputValue.query))); + result.emplace_back(R"js(operationName)js"s, ModifiedVariable::serialize(std::move(inputValue.operationName))); + result.emplace_back(R"js(variables)js"s, ModifiedVariable::serialize(std::move(inputValue.variables))); + + return result; +} + +template <> +OperationType Response::parse(response::Value&& value) +{ + if (!value.maybe_enum()) + { + throw std::logic_error { R"ex(not a valid OperationType value)ex" }; + } + + static const std::array, 3> s_values = { + std::make_pair(R"gql(QUERY)gql"sv, OperationType::QUERY), + std::make_pair(R"gql(MUTATION)gql"sv, OperationType::MUTATION), + std::make_pair(R"gql(SUBSCRIPTION)gql"sv, OperationType::SUBSCRIPTION) + }; + + const auto result = internal::sorted_map_lookup( + s_values, + std::string_view { value.get() }); + + if (!result) + { + throw std::logic_error { R"ex(not a valid OperationType value)ex" }; + } + + return *result; +} + +template <> +graphql::proxy::client::query::relayQuery::Response::relay_QueryResults Response::parse(response::Value&& response) { - graphql::proxy::client::query::relayQuery::Response::relay_Results result; + graphql::proxy::client::query::relayQuery::Response::relay_QueryResults result; if (response.type() == response::Type::Map) { @@ -101,9 +157,7 @@ response::Value serializeVariables(Variables&& variables) response::Value result { response::Type::Map }; - result.emplace_back(R"js(query)js"s, ModifiedVariable::serialize(std::move(variables.query))); - result.emplace_back(R"js(operationName)js"s, ModifiedVariable::serialize(std::move(variables.operationName))); - result.emplace_back(R"js(variables)js"s, ModifiedVariable::serialize(std::move(variables.variables))); + result.emplace_back(R"js(input)js"s, ModifiedVariable::serialize(std::move(variables.input))); return result; } @@ -122,7 +176,7 @@ Response parseResponse(response::Value&& response) { if (member.first == R"js(relay)js"sv) { - result.relay = ModifiedResponse::parse(std::move(member.second)); + result.relay = ModifiedResponse::parse(std::move(member.second)); continue; } } diff --git a/samples/proxy/query/ProxyClient.h b/samples/proxy/query/ProxyClient.h index 90e75ad0..f541794f 100644 --- a/samples/proxy/query/ProxyClient.h +++ b/samples/proxy/query/ProxyClient.h @@ -14,6 +14,8 @@ #include "graphqlservice/internal/Version.h" +#include "ProxySchema.h" + #include #include #include @@ -29,8 +31,8 @@ namespace graphql::proxy { /// # Copyright (c) Microsoft Corporation. All rights reserved. /// # Licensed under the MIT License. /// -/// query relayQuery($query: String!, $operationName: String, $variables: String) { -/// relay(query: $query, operationName: $operationName, variables: $variables) { +/// query relayQuery($input: QueryInput!) { +/// relay(input: $input) { /// data /// errors /// } @@ -52,24 +54,26 @@ using graphql::proxy::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; +using graphql::proxy::OperationType; + +using graphql::proxy::QueryInput; + struct [[nodiscard("unnecessary construction")]] Variables { - std::string query {}; - std::optional operationName {}; - std::optional variables {}; + QueryInput input {}; }; [[nodiscard("unnecessary conversion")]] response::Value serializeVariables(Variables&& variables); struct [[nodiscard("unnecessary construction")]] Response { - struct [[nodiscard("unnecessary construction")]] relay_Results + struct [[nodiscard("unnecessary construction")]] relay_QueryResults { std::optional data {}; std::optional>> errors {}; }; - relay_Results relay {}; + relay_QueryResults relay {}; }; [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); diff --git a/samples/proxy/query/ProxyClient.ixx b/samples/proxy/query/ProxyClient.ixx index 8151c844..d83227a1 100644 --- a/samples/proxy/query/ProxyClient.ixx +++ b/samples/proxy/query/ProxyClient.ixx @@ -16,12 +16,24 @@ namespace client { using client::GetRequestText; using client::GetRequestObject; +} // namespace client + +using proxy::OperationType; + +using proxy::QueryInput; + +namespace client { + namespace query::relayQuery { using graphql::proxy::client::GetRequestText; using graphql::proxy::client::GetRequestObject; using relayQuery::GetOperationName; +using graphql::proxy::OperationType; + +using graphql::proxy::QueryInput; + using relayQuery::Variables; using relayQuery::serializeVariables; diff --git a/samples/proxy/query/query.graphql b/samples/proxy/query/query.graphql index 54ca8e60..63567f4b 100644 --- a/samples/proxy/query/query.graphql +++ b/samples/proxy/query/query.graphql @@ -1,8 +1,8 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -query relayQuery($query: String!, $operationName: String, $variables: String) { - relay(query: $query, operationName: $operationName, variables: $variables) { +query relayQuery($input: QueryInput!) { + relay(input: $input) { data errors } diff --git a/samples/proxy/schema/ProxySchema.cpp b/samples/proxy/schema/ProxySchema.cpp index a4ef637d..5f2c26b4 100644 --- a/samples/proxy/schema/ProxySchema.cpp +++ b/samples/proxy/schema/ProxySchema.cpp @@ -21,8 +21,145 @@ using namespace std::literals; namespace graphql { +namespace service { + +static const auto s_namesOperationType = proxy::getOperationTypeNames(); +static const auto s_valuesOperationType = proxy::getOperationTypeValues(); + +template <> +proxy::OperationType Argument::convert(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; + } + + const auto result = internal::sorted_map_lookup( + s_valuesOperationType, + std::string_view { value.get() }); + + if (!result) + { + throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; + } + + return *result; +} + +template <> +service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), std::move(params), + [](proxy::OperationType value, const ResolverParams&) + { + response::Value resolvedResult(response::Type::EnumValue); + + resolvedResult.set(std::string { s_namesOperationType[static_cast(value)] }); + + return resolvedResult; + }); +} + +template <> +void Result::validateScalar(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; + } + + const auto [itr, itrEnd] = internal::sorted_map_equal_range( + s_valuesOperationType.begin(), + s_valuesOperationType.end(), + std::string_view { value.get() }); + + if (itr == itrEnd) + { + throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; + } +} + +template <> +proxy::QueryInput Argument::convert(const response::Value& value) +{ + auto valueType = service::ModifiedArgument::require("type", value); + auto valueQuery = service::ModifiedArgument::require("query", value); + auto valueOperationName = service::ModifiedArgument::require("operationName", value); + auto valueVariables = service::ModifiedArgument::require("variables", value); + + return proxy::QueryInput { + std::move(valueType), + std::move(valueQuery), + std::move(valueOperationName), + std::move(valueVariables) + }; +} + +} // namespace service + namespace proxy { +QueryInput::QueryInput() noexcept + : type {} + , query {} + , operationName {} + , variables {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +QueryInput::QueryInput( + OperationType typeArg, + std::string queryArg, + std::optional operationNameArg, + std::optional variablesArg) noexcept + : type { std::move(typeArg) } + , query { std::move(queryArg) } + , operationName { std::move(operationNameArg) } + , variables { std::move(variablesArg) } +{ +} + +QueryInput::QueryInput(const QueryInput& other) + : type { service::ModifiedArgument::duplicate(other.type) } + , query { service::ModifiedArgument::duplicate(other.query) } + , operationName { service::ModifiedArgument::duplicate(other.operationName) } + , variables { service::ModifiedArgument::duplicate(other.variables) } +{ +} + +QueryInput::QueryInput(QueryInput&& other) noexcept + : type { std::move(other.type) } + , query { std::move(other.query) } + , operationName { std::move(other.operationName) } + , variables { std::move(other.variables) } +{ +} + +QueryInput::~QueryInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +QueryInput& QueryInput::operator=(const QueryInput& other) +{ + QueryInput value { other }; + + std::swap(*this, value); + + return *this; +} + +QueryInput& QueryInput::operator=(QueryInput&& other) noexcept +{ + type = std::move(other.type); + query = std::move(other.query); + operationName = std::move(other.operationName); + variables = std::move(other.variables); + + return *this; +} + Operations::Operations(std::shared_ptr query) : service::Request({ { service::strQuery, query } @@ -33,13 +170,30 @@ Operations::Operations(std::shared_ptr query) void AddTypesToSchema(const std::shared_ptr& schema) { + auto typeOperationType = schema::EnumType::Make(R"gql(OperationType)gql"sv, R"md()md"sv); + schema->AddType(R"gql(OperationType)gql"sv, typeOperationType); + auto typeQueryInput = schema::InputObjectType::Make(R"gql(QueryInput)gql"sv, R"md()md"sv); + schema->AddType(R"gql(QueryInput)gql"sv, typeQueryInput); auto typeQuery = schema::ObjectType::Make(R"gql(Query)gql"sv, R"md()md"sv); schema->AddType(R"gql(Query)gql"sv, typeQuery); - auto typeResults = schema::ObjectType::Make(R"gql(Results)gql"sv, R"md()md"sv); - schema->AddType(R"gql(Results)gql"sv, typeResults); + auto typeQueryResults = schema::ObjectType::Make(R"gql(QueryResults)gql"sv, R"md()md"sv); + schema->AddType(R"gql(QueryResults)gql"sv, typeQueryResults); + + typeOperationType->AddEnumValues({ + { service::s_namesOperationType[static_cast(proxy::OperationType::QUERY)], R"md()md"sv, std::nullopt }, + { service::s_namesOperationType[static_cast(proxy::OperationType::MUTATION)], R"md()md"sv, std::nullopt }, + { service::s_namesOperationType[static_cast(proxy::OperationType::SUBSCRIPTION)], R"md()md"sv, std::nullopt } + }); + + typeQueryInput->AddInputValues({ + schema::InputValue::Make(R"gql(type)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(OperationType)gql"sv)), R"gql()gql"sv), + schema::InputValue::Make(R"gql(query)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(String)gql"sv)), R"gql()gql"sv), + schema::InputValue::Make(R"gql(operationName)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql(null)gql"sv), + schema::InputValue::Make(R"gql(variables)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql(null)gql"sv) + }); AddQueryDetails(typeQuery, schema); - AddResultsDetails(typeResults, schema); + AddQueryResultsDetails(typeQueryResults, schema); schema->AddQueryType(typeQuery); } diff --git a/samples/proxy/schema/ProxySchema.h b/samples/proxy/schema/ProxySchema.h index 9d4e544d..849cfb60 100644 --- a/samples/proxy/schema/ProxySchema.h +++ b/samples/proxy/schema/ProxySchema.h @@ -25,10 +25,61 @@ static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: namespace graphql { namespace proxy { + +enum class [[nodiscard("unnecessary conversion")]] OperationType +{ + QUERY, + MUTATION, + SUBSCRIPTION +}; + +[[nodiscard("unnecessary call")]] constexpr auto getOperationTypeNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(QUERY)gql"sv, + R"gql(MUTATION)gql"sv, + R"gql(SUBSCRIPTION)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getOperationTypeValues() noexcept +{ + using namespace std::literals; + + return std::array, 3> { + std::make_pair(R"gql(QUERY)gql"sv, OperationType::QUERY), + std::make_pair(R"gql(MUTATION)gql"sv, OperationType::MUTATION), + std::make_pair(R"gql(SUBSCRIPTION)gql"sv, OperationType::SUBSCRIPTION) + }; +} + +struct [[nodiscard("unnecessary construction")]] QueryInput +{ + explicit QueryInput() noexcept; + explicit QueryInput( + OperationType typeArg, + std::string queryArg, + std::optional operationNameArg, + std::optional variablesArg) noexcept; + QueryInput(const QueryInput& other); + QueryInput(QueryInput&& other) noexcept; + ~QueryInput(); + + QueryInput& operator=(const QueryInput& other); + QueryInput& operator=(QueryInput&& other) noexcept; + + OperationType type; + std::string query; + std::optional operationName; + std::optional variables; +}; + namespace object { class Query; -class Results; +class QueryResults; } // namespace object @@ -51,7 +102,7 @@ class [[nodiscard("unnecessary construction")]] Operations final }; void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema); -void AddResultsDetails(const std::shared_ptr& typeResults, const std::shared_ptr& schema); +void AddQueryResultsDetails(const std::shared_ptr& typeQueryResults, const std::shared_ptr& schema); std::shared_ptr GetSchema(); diff --git a/samples/proxy/schema/ProxySchema.ixx b/samples/proxy/schema/ProxySchema.ixx index c0b1b5b2..0b646c10 100644 --- a/samples/proxy/schema/ProxySchema.ixx +++ b/samples/proxy/schema/ProxySchema.ixx @@ -10,14 +10,20 @@ module; export module GraphQL.Proxy.ProxySchema; export import GraphQL.Proxy.QueryObject; -export import GraphQL.Proxy.ResultsObject; +export import GraphQL.Proxy.QueryResultsObject; export namespace graphql::proxy { +using proxy::OperationType; +using proxy::getOperationTypeNames; +using proxy::getOperationTypeValues; + +using proxy::QueryInput; + using proxy::Operations; using proxy::AddQueryDetails; -using proxy::AddResultsDetails; +using proxy::AddQueryResultsDetails; using proxy::GetSchema; diff --git a/samples/proxy/schema/QueryObject.cpp b/samples/proxy/schema/QueryObject.cpp index d4dfb635..cdfc3817 100644 --- a/samples/proxy/schema/QueryObject.cpp +++ b/samples/proxy/schema/QueryObject.cpp @@ -4,7 +4,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. #include "QueryObject.h" -#include "ResultsObject.h" +#include "QueryResultsObject.h" #include "graphqlservice/internal/Introspection.h" @@ -57,16 +57,14 @@ void Query::endSelectionSet(const service::SelectionSetParams& params) const service::AwaitableResolver Query::resolveRelay(service::ResolverParams&& params) const { - auto argQuery = service::ModifiedArgument::require("query", params.arguments); - auto argOperationName = service::ModifiedArgument::require("operationName", params.arguments); - auto argVariables = service::ModifiedArgument::require("variables", params.arguments); + auto argInput = service::ModifiedArgument::require("input", params.arguments); std::unique_lock resolverLock(_resolverMutex); service::SelectionSetParams selectionSetParams { static_cast(params) }; auto directives = std::move(params.fieldDirectives); - auto result = _pimpl->getRelay(service::FieldParams { std::move(selectionSetParams), std::move(directives) }, std::move(argQuery), std::move(argOperationName), std::move(argVariables)); + auto result = _pimpl->getRelay(service::FieldParams { std::move(selectionSetParams), std::move(directives) }, std::move(argInput)); resolverLock.unlock(); - return service::ModifiedResult::convert(std::move(result), std::move(params)); + return service::ModifiedResult::convert(std::move(result), std::move(params)); } service::AwaitableResolver Query::resolve_typename(service::ResolverParams&& params) const @@ -93,10 +91,8 @@ service::AwaitableResolver Query::resolve_type(service::ResolverParams&& params) void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) { typeQuery->AddFields({ - schema::Field::Make(R"gql(relay)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(Results)gql"sv)), { - schema::InputValue::Make(R"gql(query)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(String)gql"sv)), R"gql()gql"sv), - schema::InputValue::Make(R"gql(operationName)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql()gql"sv), - schema::InputValue::Make(R"gql(variables)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql()gql"sv) + schema::Field::Make(R"gql(relay)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(QueryResults)gql"sv)), { + schema::InputValue::Make(R"gql(input)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(QueryInput)gql"sv)), R"gql()gql"sv) }) }); } diff --git a/samples/proxy/schema/QueryObject.h b/samples/proxy/schema/QueryObject.h index 0afd51de..ed350a05 100644 --- a/samples/proxy/schema/QueryObject.h +++ b/samples/proxy/schema/QueryObject.h @@ -14,15 +14,15 @@ namespace graphql::proxy::object { namespace methods::QueryHas { template -concept getRelayWithParams = requires (TImpl impl, service::FieldParams params, std::string queryArg, std::optional operationNameArg, std::optional variablesArg) +concept getRelayWithParams = requires (TImpl impl, service::FieldParams params, QueryInput inputArg) { - { service::AwaitableObject> { impl.getRelay(std::move(params), std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) } }; + { service::AwaitableObject> { impl.getRelay(std::move(params), std::move(inputArg)) } }; }; template -concept getRelay = requires (TImpl impl, std::string queryArg, std::optional operationNameArg, std::optional variablesArg) +concept getRelay = requires (TImpl impl, QueryInput inputArg) { - { service::AwaitableObject> { impl.getRelay(std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) } }; + { service::AwaitableObject> { impl.getRelay(std::move(inputArg)) } }; }; template @@ -58,7 +58,7 @@ class [[nodiscard("unnecessary construction")]] Query final virtual void beginSelectionSet(const service::SelectionSetParams& params) const = 0; virtual void endSelectionSet(const service::SelectionSetParams& params) const = 0; - [[nodiscard("unnecessary call")]] virtual service::AwaitableObject> getRelay(service::FieldParams&& params, std::string&& queryArg, std::optional&& operationNameArg, std::optional&& variablesArg) const = 0; + [[nodiscard("unnecessary call")]] virtual service::AwaitableObject> getRelay(service::FieldParams&& params, QueryInput&& inputArg) const = 0; }; template @@ -70,16 +70,16 @@ class [[nodiscard("unnecessary construction")]] Query final { } - [[nodiscard("unnecessary call")]] service::AwaitableObject> getRelay(service::FieldParams&& params, std::string&& queryArg, std::optional&& operationNameArg, std::optional&& variablesArg) const override + [[nodiscard("unnecessary call")]] service::AwaitableObject> getRelay(service::FieldParams&& params, QueryInput&& inputArg) const override { if constexpr (methods::QueryHas::getRelayWithParams) { - return { _pimpl->getRelay(std::move(params), std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) }; + return { _pimpl->getRelay(std::move(params), std::move(inputArg)) }; } else { static_assert(methods::QueryHas::getRelay, R"msg(Query::getRelay is not implemented)msg"); - return { _pimpl->getRelay(std::move(queryArg), std::move(operationNameArg), std::move(variablesArg)) }; + return { _pimpl->getRelay(std::move(inputArg)) }; } } diff --git a/samples/proxy/schema/ResultsObject.cpp b/samples/proxy/schema/QueryResultsObject.cpp similarity index 73% rename from samples/proxy/schema/ResultsObject.cpp rename to samples/proxy/schema/QueryResultsObject.cpp index 444f4b81..80d2e5f0 100644 --- a/samples/proxy/schema/ResultsObject.cpp +++ b/samples/proxy/schema/QueryResultsObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "ResultsObject.h" +#include "QueryResultsObject.h" #include "graphqlservice/internal/Schema.h" @@ -19,20 +19,20 @@ using namespace std::literals; namespace graphql::proxy { namespace object { -Results::Results(std::unique_ptr pimpl) noexcept +QueryResults::QueryResults(std::unique_ptr pimpl) noexcept : service::Object{ getTypeNames(), getResolvers() } , _pimpl { std::move(pimpl) } { } -service::TypeNames Results::getTypeNames() const noexcept +service::TypeNames QueryResults::getTypeNames() const noexcept { return { - R"gql(Results)gql"sv + R"gql(QueryResults)gql"sv }; } -service::ResolverMap Results::getResolvers() const noexcept +service::ResolverMap QueryResults::getResolvers() const noexcept { return { { R"gql(data)gql"sv, [this](service::ResolverParams&& params) { return resolveData(std::move(params)); } }, @@ -41,17 +41,17 @@ service::ResolverMap Results::getResolvers() const noexcept }; } -void Results::beginSelectionSet(const service::SelectionSetParams& params) const +void QueryResults::beginSelectionSet(const service::SelectionSetParams& params) const { _pimpl->beginSelectionSet(params); } -void Results::endSelectionSet(const service::SelectionSetParams& params) const +void QueryResults::endSelectionSet(const service::SelectionSetParams& params) const { _pimpl->endSelectionSet(params); } -service::AwaitableResolver Results::resolveData(service::ResolverParams&& params) const +service::AwaitableResolver QueryResults::resolveData(service::ResolverParams&& params) const { std::unique_lock resolverLock(_resolverMutex); service::SelectionSetParams selectionSetParams { static_cast(params) }; @@ -62,7 +62,7 @@ service::AwaitableResolver Results::resolveData(service::ResolverParams&& params return service::ModifiedResult::convert(std::move(result), std::move(params)); } -service::AwaitableResolver Results::resolveErrors(service::ResolverParams&& params) const +service::AwaitableResolver QueryResults::resolveErrors(service::ResolverParams&& params) const { std::unique_lock resolverLock(_resolverMutex); service::SelectionSetParams selectionSetParams { static_cast(params) }; @@ -73,16 +73,16 @@ service::AwaitableResolver Results::resolveErrors(service::ResolverParams&& para return service::ModifiedResult::convert(std::move(result), std::move(params)); } -service::AwaitableResolver Results::resolve_typename(service::ResolverParams&& params) const +service::AwaitableResolver QueryResults::resolve_typename(service::ResolverParams&& params) const { - return service::Result::convert(std::string{ R"gql(Results)gql" }, std::move(params)); + return service::Result::convert(std::string{ R"gql(QueryResults)gql" }, std::move(params)); } } // namespace object -void AddResultsDetails(const std::shared_ptr& typeResults, const std::shared_ptr& schema) +void AddQueryResultsDetails(const std::shared_ptr& typeQueryResults, const std::shared_ptr& schema) { - typeResults->AddFields({ + typeQueryResults->AddFields({ schema::Field::Make(R"gql(data)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv)), schema::Field::Make(R"gql(errors)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::LIST, schema->LookupType(R"gql(String)gql"sv))) }); diff --git a/samples/proxy/schema/ResultsObject.h b/samples/proxy/schema/QueryResultsObject.h similarity index 80% rename from samples/proxy/schema/ResultsObject.h rename to samples/proxy/schema/QueryResultsObject.h index 51718f38..bd4ef01e 100644 --- a/samples/proxy/schema/ResultsObject.h +++ b/samples/proxy/schema/QueryResultsObject.h @@ -5,13 +5,13 @@ #pragma once -#ifndef RESULTSOBJECT_H -#define RESULTSOBJECT_H +#ifndef QUERYRESULTSOBJECT_H +#define QUERYRESULTSOBJECT_H #include "ProxySchema.h" namespace graphql::proxy::object { -namespace methods::ResultsHas { +namespace methods::QueryResultsHas { template concept getDataWithParams = requires (TImpl impl, service::FieldParams params) @@ -49,9 +49,9 @@ concept endSelectionSet = requires (TImpl impl, const service::SelectionSetParam { impl.endSelectionSet(params) }; }; -} // namespace methods::ResultsHas +} // namespace methods::QueryResultsHas -class [[nodiscard("unnecessary construction")]] Results final +class [[nodiscard("unnecessary construction")]] QueryResults final : public service::Object { private: @@ -82,33 +82,33 @@ class [[nodiscard("unnecessary construction")]] Results final [[nodiscard("unnecessary call")]] service::AwaitableScalar> getData(service::FieldParams&& params) const override { - if constexpr (methods::ResultsHas::getDataWithParams) + if constexpr (methods::QueryResultsHas::getDataWithParams) { return { _pimpl->getData(std::move(params)) }; } else { - static_assert(methods::ResultsHas::getData, R"msg(Results::getData is not implemented)msg"); + static_assert(methods::QueryResultsHas::getData, R"msg(QueryResults::getData is not implemented)msg"); return { _pimpl->getData() }; } } [[nodiscard("unnecessary call")]] service::AwaitableScalar>>> getErrors(service::FieldParams&& params) const override { - if constexpr (methods::ResultsHas::getErrorsWithParams) + if constexpr (methods::QueryResultsHas::getErrorsWithParams) { return { _pimpl->getErrors(std::move(params)) }; } else { - static_assert(methods::ResultsHas::getErrors, R"msg(Results::getErrors is not implemented)msg"); + static_assert(methods::QueryResultsHas::getErrors, R"msg(QueryResults::getErrors is not implemented)msg"); return { _pimpl->getErrors() }; } } void beginSelectionSet(const service::SelectionSetParams& params) const override { - if constexpr (methods::ResultsHas::beginSelectionSet) + if constexpr (methods::QueryResultsHas::beginSelectionSet) { _pimpl->beginSelectionSet(params); } @@ -116,7 +116,7 @@ class [[nodiscard("unnecessary construction")]] Results final void endSelectionSet(const service::SelectionSetParams& params) const override { - if constexpr (methods::ResultsHas::endSelectionSet) + if constexpr (methods::QueryResultsHas::endSelectionSet) { _pimpl->endSelectionSet(params); } @@ -126,7 +126,7 @@ class [[nodiscard("unnecessary construction")]] Results final const std::shared_ptr _pimpl; }; - explicit Results(std::unique_ptr pimpl) noexcept; + explicit QueryResults(std::unique_ptr pimpl) noexcept; [[nodiscard("unnecessary call")]] service::TypeNames getTypeNames() const noexcept; [[nodiscard("unnecessary call")]] service::ResolverMap getResolvers() const noexcept; @@ -138,17 +138,17 @@ class [[nodiscard("unnecessary construction")]] Results final public: template - explicit Results(std::shared_ptr pimpl) noexcept - : Results { std::unique_ptr { std::make_unique>(std::move(pimpl)) } } + explicit QueryResults(std::shared_ptr pimpl) noexcept + : QueryResults { std::unique_ptr { std::make_unique>(std::move(pimpl)) } } { } [[nodiscard("unnecessary call")]] static constexpr std::string_view getObjectType() noexcept { - return { R"gql(Results)gql" }; + return { R"gql(QueryResults)gql" }; } }; } // namespace graphql::proxy::object -#endif // RESULTSOBJECT_H +#endif // QUERYRESULTSOBJECT_H diff --git a/samples/proxy/schema/ResultsObject.ixx b/samples/proxy/schema/QueryResultsObject.ixx similarity index 71% rename from samples/proxy/schema/ResultsObject.ixx rename to samples/proxy/schema/QueryResultsObject.ixx index 7f451cc6..27514748 100644 --- a/samples/proxy/schema/ResultsObject.ixx +++ b/samples/proxy/schema/QueryResultsObject.ixx @@ -5,12 +5,12 @@ module; -#include "ResultsObject.h" +#include "QueryResultsObject.h" -export module GraphQL.Proxy.ResultsObject; +export module GraphQL.Proxy.QueryResultsObject; export namespace graphql::proxy::object { -using object::Results; +using object::QueryResults; } // namespace graphql::proxy::object diff --git a/samples/proxy/schema/proxy_schema_files b/samples/proxy/schema/proxy_schema_files index b2805af2..3b54c3a5 100644 --- a/samples/proxy/schema/proxy_schema_files +++ b/samples/proxy/schema/proxy_schema_files @@ -1,3 +1,3 @@ ProxySchema.cpp QueryObject.cpp -ResultsObject.cpp +QueryResultsObject.cpp diff --git a/samples/proxy/schema/schema.graphql b/samples/proxy/schema/schema.graphql index fd32b986..02d9cde0 100644 --- a/samples/proxy/schema/schema.graphql +++ b/samples/proxy/schema/schema.graphql @@ -2,10 +2,23 @@ # Licensed under the MIT License. type Query { - relay(query: String!, operationName: String, variables: String): Results! + relay(input: QueryInput!): QueryResults! } -type Results { +enum OperationType { + QUERY + MUTATION + SUBSCRIPTION +} + +input QueryInput { + type: OperationType! + query: String! + operationName: String = null + variables: String = null +} + +type QueryResults { data: String errors: [String] } diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index f8be81e8..8dc873ba 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -192,7 +192,17 @@ bool Generator::outputHeader() const noexcept #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/internal/Version.h" +)cpp"; + if (_requestLoader.useSharedTypes()) + { + headerFile << R"cpp( +#include ")cpp" << _schemaLoader.getFilenamePrefix() + << R"cpp(Schema.h" +)cpp"; + } + + headerFile << R"cpp( #include #include #include @@ -220,141 +230,146 @@ static_assert(graphql::internal::MinorVersion == )cpp" outputGetRequestDeclaration(headerFile); const auto& operations = _requestLoader.getOperations(); - std::unordered_set declaredEnum; - for (const auto& operation : operations) + if (!_requestLoader.useSharedTypes()) { - // Define all of the enums referenced either in variables or the response. - for (const auto& enumType : _requestLoader.getReferencedEnums(operation)) - { - const auto cppType = _schemaLoader.getCppType(enumType->name()); + std::unordered_set declaredEnum; - if (!declaredEnum.insert(cppType).second) + for (const auto& operation : operations) + { + // Define all of the enums referenced either in variables or the response. + for (const auto& enumType : _requestLoader.getReferencedEnums(operation)) { - continue; - } + const auto cppType = _schemaLoader.getCppType(enumType->name()); - pendingSeparator.reset(); + if (!declaredEnum.insert(cppType).second) + { + continue; + } - if (clientNamespaceScope.exit()) - { - headerFile << std::endl; - } + pendingSeparator.reset(); + + if (clientNamespaceScope.exit()) + { + headerFile << std::endl; + } - headerFile << R"cpp(enum class [[nodiscard("unnecessary conversion")]] )cpp" << cppType - << R"cpp( + headerFile << R"cpp(enum class [[nodiscard("unnecessary conversion")]] )cpp" + << cppType << R"cpp( { )cpp"; - for (const auto& enumValue : enumType->enumValues()) - { - headerFile << R"cpp( )cpp" << SchemaLoader::getSafeCppName(enumValue->name()) - << R"cpp(, + for (const auto& enumValue : enumType->enumValues()) + { + headerFile << R"cpp( )cpp" << SchemaLoader::getSafeCppName(enumValue->name()) + << R"cpp(, )cpp"; - } + } - headerFile << R"cpp(}; + headerFile << R"cpp(}; )cpp"; - pendingSeparator.add(); + pendingSeparator.add(); + } } - } - std::unordered_set declaredInput; - std::unordered_set forwardDeclaredInput; + std::unordered_set declaredInput; + std::unordered_set forwardDeclaredInput; - for (const auto& operation : operations) - { - // Define all of the input object structs referenced in variables. - for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) + for (const auto& operation : operations) { - const auto cppType = _schemaLoader.getCppType(inputType.type->name()); - - if (!declaredInput.insert(cppType).second) + // Define all of the input object structs referenced in variables. + for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) { - continue; - } + const auto cppType = _schemaLoader.getCppType(inputType.type->name()); - pendingSeparator.reset(); + if (!declaredInput.insert(cppType).second) + { + continue; + } - if (clientNamespaceScope.exit()) - { - headerFile << std::endl; - } + pendingSeparator.reset(); - if (!inputType.declarations.empty()) - { - // Forward declare nullable dependencies - for (auto declaration : inputType.declarations) + if (clientNamespaceScope.exit()) { - if (declaredInput.find(declaration) == declaredInput.end() - && forwardDeclaredInput.insert(declaration).second) + headerFile << std::endl; + } + + if (!inputType.declarations.empty()) + { + // Forward declare nullable dependencies + for (auto declaration : inputType.declarations) { - headerFile << R"cpp(struct )cpp" << declaration << R"cpp(; + if (declaredInput.find(declaration) == declaredInput.end() + && forwardDeclaredInput.insert(declaration).second) + { + headerFile << R"cpp(struct )cpp" << declaration << R"cpp(; )cpp"; - pendingSeparator.add(); + pendingSeparator.add(); + } } - } - pendingSeparator.reset(); - } + pendingSeparator.reset(); + } - headerFile << R"cpp(struct [[nodiscard("unnecessary construction")]] )cpp" << cppType - << R"cpp( + headerFile << R"cpp(struct [[nodiscard("unnecessary construction")]] )cpp" + << cppType << R"cpp( { explicit )cpp" << cppType - << R"cpp(()cpp"; + << R"cpp(()cpp"; - bool firstField = true; + bool firstField = true; - for (const auto& inputField : inputType.type->inputFields()) - { - if (firstField) + for (const auto& inputField : inputType.type->inputFields()) { - headerFile << R"cpp() noexcept; + if (firstField) + { + headerFile << R"cpp() noexcept; explicit )cpp" << cppType << R"cpp(()cpp"; - } - else - { - headerFile << R"cpp(,)cpp"; - } + } + else + { + headerFile << R"cpp(,)cpp"; + } - firstField = false; + firstField = false; - const auto inputCppType = _requestLoader.getInputCppType(inputField->type().lock()); + const auto inputCppType = + _requestLoader.getInputCppType(inputField->type().lock()); - headerFile << R"cpp( - )cpp" << inputCppType - << R"cpp( )cpp" << SchemaLoader::getSafeCppName(inputField->name()) - << R"cpp(Arg)cpp"; - } + headerFile << R"cpp( + )cpp" << inputCppType << R"cpp( )cpp" + << SchemaLoader::getSafeCppName(inputField->name()) + << R"cpp(Arg)cpp"; + } - headerFile << R"cpp() noexcept; + headerFile << R"cpp() noexcept; )cpp" << cppType << R"cpp((const )cpp" - << cppType << R"cpp(& other); + << cppType << R"cpp(& other); )cpp" << cppType << R"cpp(()cpp" - << cppType << R"cpp(&& other) noexcept; + << cppType << R"cpp(&& other) noexcept; ~)cpp" << cppType << R"cpp((); )cpp" << cppType << R"cpp(& operator=(const )cpp" - << cppType << R"cpp(& other); + << cppType << R"cpp(& other); )cpp" << cppType << R"cpp(& operator=()cpp" - << cppType << R"cpp(&& other) noexcept; + << cppType << R"cpp(&& other) noexcept; )cpp"; - for (const auto& inputField : inputType.type->inputFields()) - { - headerFile << R"cpp( )cpp" - << _requestLoader.getInputCppType(inputField->type().lock()) - << R"cpp( )cpp" << SchemaLoader::getSafeCppName(inputField->name()) - << R"cpp(; + for (const auto& inputField : inputType.type->inputFields()) + { + headerFile << R"cpp( )cpp" + << _requestLoader.getInputCppType(inputField->type().lock()) + << R"cpp( )cpp" << SchemaLoader::getSafeCppName(inputField->name()) + << R"cpp(; )cpp"; - } + } - headerFile << R"cpp(}; + headerFile << R"cpp(}; )cpp"; - pendingSeparator.add(); + pendingSeparator.add(); + } } } @@ -855,164 +870,170 @@ using namespace std::literals; outputGetRequestImplementation(sourceFile); const auto& operations = _requestLoader.getOperations(); - std::unordered_set outputInputMethods; - for (const auto& operation : operations) + if (!_requestLoader.useSharedTypes()) { - for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) - { - const auto cppType = _schemaLoader.getCppType(inputType.type->name()); - if (!outputInputMethods.insert(cppType).second) + std::unordered_set outputInputMethods; + + for (const auto& operation : operations) + { + for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) { - continue; - } + const auto cppType = _schemaLoader.getCppType(inputType.type->name()); - pendingSeparator.reset(); + if (!outputInputMethods.insert(cppType).second) + { + continue; + } - if (clientNamespaceScope.exit()) - { - sourceFile << R"cpp( -using namespace graphql::)cpp" - << getClientNamespace() << R"cpp(; + pendingSeparator.reset(); + + if (clientNamespaceScope.exit()) + { + sourceFile << R"cpp( +using namespace graphql::)cpp" << getClientNamespace() + << R"cpp(; )cpp"; - } + } - sourceFile << cppType << R"cpp(::)cpp" << cppType << R"cpp(() noexcept)cpp"; + sourceFile << cppType << R"cpp(::)cpp" << cppType << R"cpp(() noexcept)cpp"; - bool firstField = true; + bool firstField = true; - for (const auto& inputField : inputType.type->inputFields()) - { - sourceFile << R"cpp( + for (const auto& inputField : inputType.type->inputFields()) + { + sourceFile << R"cpp( )cpp" << (firstField ? R"cpp(:)cpp" : R"cpp(,)cpp") - << R"cpp( )cpp" << SchemaLoader::getSafeCppName(inputField->name()) - << R"cpp( {})cpp"; - firstField = false; - } + << R"cpp( )cpp" << SchemaLoader::getSafeCppName(inputField->name()) + << R"cpp( {})cpp"; + firstField = false; + } - sourceFile << R"cpp( + sourceFile << R"cpp( { // Explicit definition to prevent ODR violations when LTO is enabled. } )cpp" << cppType << R"cpp(::)cpp" - << cppType << R"cpp(()cpp"; + << cppType << R"cpp(()cpp"; - firstField = true; + firstField = true; - for (const auto& inputField : inputType.type->inputFields()) - { - if (!firstField) + for (const auto& inputField : inputType.type->inputFields()) { - sourceFile << R"cpp(,)cpp"; - } + if (!firstField) + { + sourceFile << R"cpp(,)cpp"; + } - firstField = false; - sourceFile << R"cpp( + firstField = false; + sourceFile << R"cpp( )cpp" << _requestLoader.getInputCppType(inputField->type().lock()) - << R"cpp( )cpp" << SchemaLoader::getSafeCppName(inputField->name()) - << R"cpp(Arg)cpp"; - } + << R"cpp( )cpp" << SchemaLoader::getSafeCppName(inputField->name()) + << R"cpp(Arg)cpp"; + } - sourceFile << R"cpp() noexcept + sourceFile << R"cpp() noexcept )cpp"; - firstField = true; + firstField = true; - for (const auto& inputField : inputType.type->inputFields()) - { - sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); - firstField = false; + for (const auto& inputField : inputType.type->inputFields()) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; - const auto name = SchemaLoader::getSafeCppName(inputField->name()); + const auto name = SchemaLoader::getSafeCppName(inputField->name()); - sourceFile << name << R"cpp( { std::move()cpp" << name << R"cpp(Arg) } + sourceFile << name << R"cpp( { std::move()cpp" << name << R"cpp(Arg) } )cpp"; - } + } - sourceFile << R"cpp({ + sourceFile << R"cpp({ } )cpp" << cppType << R"cpp(::)cpp" - << cppType << R"cpp((const )cpp" << cppType << R"cpp(& other) + << cppType << R"cpp((const )cpp" << cppType << R"cpp(& other) )cpp"; - firstField = true; + firstField = true; - for (const auto& inputField : inputType.type->inputFields()) - { - sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); - firstField = false; + for (const auto& inputField : inputType.type->inputFields()) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; - const auto name = SchemaLoader::getSafeCppName(inputField->name()); - const auto [type, modifiers] = - RequestLoader::unwrapSchemaType(inputField->type().lock()); + const auto name = SchemaLoader::getSafeCppName(inputField->name()); + const auto [type, modifiers] = + RequestLoader::unwrapSchemaType(inputField->type().lock()); - sourceFile << name << R"cpp( { ModifiedVariable<)cpp" - << _schemaLoader.getCppType(type->name()) << R"cpp(>::duplicate)cpp" - << getTypeModifierList(modifiers) << R"cpp((other.)cpp" << name - << R"cpp() } + sourceFile << name << R"cpp( { ModifiedVariable<)cpp" + << _schemaLoader.getCppType(type->name()) << R"cpp(>::duplicate)cpp" + << getTypeModifierList(modifiers) << R"cpp((other.)cpp" << name + << R"cpp() } )cpp"; - } + } - sourceFile << R"cpp({ + sourceFile << R"cpp({ } )cpp" << cppType << R"cpp(::)cpp" - << cppType << R"cpp(()cpp" << cppType << R"cpp(&& other) noexcept + << cppType << R"cpp(()cpp" << cppType << R"cpp(&& other) noexcept )cpp"; - firstField = true; + firstField = true; - for (const auto& inputField : inputType.type->inputFields()) - { - sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); - firstField = false; + for (const auto& inputField : inputType.type->inputFields()) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; - const auto name = SchemaLoader::getSafeCppName(inputField->name()); + const auto name = SchemaLoader::getSafeCppName(inputField->name()); - sourceFile << name << R"cpp( { std::move(other.)cpp" << name << R"cpp() } + sourceFile << name << R"cpp( { std::move(other.)cpp" << name << R"cpp() } )cpp"; - } + } - sourceFile << R"cpp({ + sourceFile << R"cpp({ } )cpp" << cppType << R"cpp(::~)cpp" - << cppType << R"cpp(() + << cppType << R"cpp(() { // Explicit definition to prevent ODR violations when LTO is enabled. } )cpp" << cppType << R"cpp(& )cpp" - << cppType << R"cpp(::operator=(const )cpp" << cppType << R"cpp(& other) + << cppType << R"cpp(::operator=(const )cpp" << cppType << R"cpp(& other) { - return *this = )cpp" - << cppType << R"cpp( { other }; + return *this = )cpp" << cppType + << R"cpp( { other }; } )cpp" << cppType << R"cpp(& )cpp" - << cppType << R"cpp(::operator=()cpp" << cppType << R"cpp(&& other) noexcept + << cppType << R"cpp(::operator=()cpp" << cppType + << R"cpp(&& other) noexcept { )cpp"; - for (const auto& inputField : inputType.type->inputFields()) - { - const auto name = SchemaLoader::getSafeCppName(inputField->name()); + for (const auto& inputField : inputType.type->inputFields()) + { + const auto name = SchemaLoader::getSafeCppName(inputField->name()); - sourceFile << R"cpp( )cpp" << name << R"cpp( = std::move(other.)cpp" << name - << R"cpp(); + sourceFile << R"cpp( )cpp" << name << R"cpp( = std::move(other.)cpp" << name + << R"cpp(); )cpp"; - } + } - sourceFile << R"cpp( + sourceFile << R"cpp( return *this; } )cpp"; - pendingSeparator.add(); + pendingSeparator.add(); + } } } @@ -1586,6 +1607,7 @@ int main(int argc, char** argv) bool buildCustom = false; bool verbose = false; bool noIntrospection = false; + bool sharedTypes = false; std::string schemaFileName; std::string requestFileName; std::string operationName; @@ -1615,7 +1637,9 @@ int main(int argc, char** argv) po::value(&headerDir), "Target path for the Client.h header file")("no-introspection", po::bool_switch(&noIntrospection), - "Do not expect support for Introspection"); + "Do not expect support for Introspection")("shared-types", + po::bool_switch(&sharedTypes), + "Re-use shared types from Schema.h"); positional.add("schema", 1).add("request", 1).add("prefix", 1).add("namespace", 1); try @@ -1677,6 +1701,7 @@ int main(int argc, char** argv) { operationName.empty() ? std::nullopt : std::make_optional(std::move(operationName)) }, noIntrospection, + sharedTypes, }, graphql::generator::client::GeneratorOptions { { std::move(headerDir), std::move(sourceDir) }, diff --git a/src/RequestLoader.cpp b/src/RequestLoader.cpp index 0e59f661..e4d3d7c4 100644 --- a/src/RequestLoader.cpp +++ b/src/RequestLoader.cpp @@ -140,6 +140,11 @@ const RequestVariableList& RequestLoader::getVariables(const Operation& operatio return operation.variables; } +bool RequestLoader::useSharedTypes() const noexcept +{ + return _requestOptions.sharedTypes; +} + const RequestInputTypeList& RequestLoader::getReferencedInputTypes( const Operation& operation) const noexcept { From 1769f19a9337f3bb976367155ffa4be75de5a9a5 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 19 Sep 2024 15:19:05 -0700 Subject: [PATCH 076/123] feat(sharetypes): enable shared types for client benchmark --- samples/client/CMakeLists.txt | 1 - samples/client/benchmark.cpp | 5 ++- samples/client/benchmark/CMakeLists.txt | 3 +- .../{BenchmarkClient.cpp => TodayClient.cpp} | 34 +++++++++---------- .../{BenchmarkClient.h => TodayClient.h} | 16 +++++---- .../{BenchmarkClient.ixx => TodayClient.ixx} | 12 +++---- .../client/benchmark/benchmark_client_files | 2 +- src/ClientGenerator.cpp | 3 +- 8 files changed, 39 insertions(+), 37 deletions(-) rename samples/client/benchmark/{BenchmarkClient.cpp => TodayClient.cpp} (64%) rename samples/client/benchmark/{BenchmarkClient.h => TodayClient.h} (92%) rename samples/client/benchmark/{BenchmarkClient.ixx => TodayClient.ixx} (64%) diff --git a/samples/client/CMakeLists.txt b/samples/client/CMakeLists.txt index a001c133..09a6036e 100644 --- a/samples/client/CMakeLists.txt +++ b/samples/client/CMakeLists.txt @@ -15,7 +15,6 @@ if(GRAPHQL_BUILD_MODULES) # client_benchmark add_executable(client_benchmark benchmark.cpp) target_link_libraries(client_benchmark PRIVATE - todaygraphql benchmark_client) if(WIN32 AND BUILD_SHARED_LIBS) diff --git a/samples/client/benchmark.cpp b/samples/client/benchmark.cpp index bd699ea8..66723db2 100644 --- a/samples/client/benchmark.cpp +++ b/samples/client/benchmark.cpp @@ -16,8 +16,7 @@ import GraphQL.Client; import GraphQL.Service; import GraphQL.Today.Mock; - -import GraphQL.Benchmark.BenchmarkClient; +import GraphQL.Today.TodayClient; using namespace graphql; @@ -93,7 +92,7 @@ int main(int argc, char** argv) try { - using namespace benchmark::client::query::Query; + using namespace today::client::query::Query; auto query = GetRequestObject(); const auto& name = GetOperationName(); diff --git a/samples/client/benchmark/CMakeLists.txt b/samples/client/benchmark/CMakeLists.txt index c2ec979e..dc132942 100644 --- a/samples/client/benchmark/CMakeLists.txt +++ b/samples/client/benchmark/CMakeLists.txt @@ -7,7 +7,8 @@ cmake_minimum_required(VERSION 3.28) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) if(GRAPHQL_UPDATE_SAMPLES AND GRAPHQL_BUILD_CLIENTGEN) - update_graphql_client_files(benchmark ../../today/schema.today.graphql client.benchmark.today.graphql Benchmark benchmark) + update_graphql_client_files(benchmark ../../today/schema.today.graphql client.benchmark.today.graphql Today today --shared-types) endif() add_graphql_client_target(benchmark) +target_link_libraries(benchmark_client PRIVATE todaygraphql) diff --git a/samples/client/benchmark/BenchmarkClient.cpp b/samples/client/benchmark/TodayClient.cpp similarity index 64% rename from samples/client/benchmark/BenchmarkClient.cpp rename to samples/client/benchmark/TodayClient.cpp index 0f9fb48b..0f65eae7 100644 --- a/samples/client/benchmark/BenchmarkClient.cpp +++ b/samples/client/benchmark/TodayClient.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "BenchmarkClient.h" +#include "TodayClient.h" #include "graphqlservice/internal/SortedMap.h" @@ -17,7 +17,7 @@ using namespace std::literals; namespace graphql { -namespace benchmark { +namespace today { namespace client { const std::string& GetRequestText() noexcept @@ -61,15 +61,15 @@ const peg::ast& GetRequestObject() noexcept } } // namespace client -} // namespace benchmark +} // namespace today namespace client { -using namespace benchmark; +using namespace today; template <> -graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo Response::parse(response::Value&& response) +graphql::today::client::query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo Response::parse(response::Value&& response) { - graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo result; + graphql::today::client::query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo result; if (response.type() == response::Type::Map) { @@ -89,9 +89,9 @@ graphql::benchmark::client::query::Query::Response::appointments_AppointmentConn } template <> -graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment Response::parse(response::Value&& response) +graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment Response::parse(response::Value&& response) { - graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result; + graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result; if (response.type() == response::Type::Map) { @@ -126,9 +126,9 @@ graphql::benchmark::client::query::Query::Response::appointments_AppointmentConn } template <> -graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge Response::parse(response::Value&& response) +graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge Response::parse(response::Value&& response) { - graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge result; + graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge result; if (response.type() == response::Type::Map) { @@ -138,7 +138,7 @@ graphql::benchmark::client::query::Query::Response::appointments_AppointmentConn { if (member.first == R"js(node)js"sv) { - result.node = ModifiedResponse::parse(std::move(member.second)); + result.node = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -148,9 +148,9 @@ graphql::benchmark::client::query::Query::Response::appointments_AppointmentConn } template <> -graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection Response::parse(response::Value&& response) +graphql::today::client::query::Query::Response::appointments_AppointmentConnection Response::parse(response::Value&& response) { - graphql::benchmark::client::query::Query::Response::appointments_AppointmentConnection result; + graphql::today::client::query::Query::Response::appointments_AppointmentConnection result; if (response.type() == response::Type::Map) { @@ -160,12 +160,12 @@ graphql::benchmark::client::query::Query::Response::appointments_AppointmentConn { if (member.first == R"js(pageInfo)js"sv) { - result.pageInfo = ModifiedResponse::parse(std::move(member.second)); + result.pageInfo = ModifiedResponse::parse(std::move(member.second)); continue; } if (member.first == R"js(edges)js"sv) { - result.edges = ModifiedResponse::parse(std::move(member.second)); + result.edges = ModifiedResponse::parse(std::move(member.second)); continue; } } @@ -176,7 +176,7 @@ graphql::benchmark::client::query::Query::Response::appointments_AppointmentConn } // namespace client -namespace benchmark::client::query::Query { +namespace today::client::query::Query { const std::string& GetOperationName() noexcept { @@ -228,5 +228,5 @@ Response parseResponse(response::Value&& response) return Query::parseResponse(std::move(response)); } -} // namespace benchmark::client::query::Query +} // namespace today::client::query::Query } // namespace graphql diff --git a/samples/client/benchmark/BenchmarkClient.h b/samples/client/benchmark/TodayClient.h similarity index 92% rename from samples/client/benchmark/BenchmarkClient.h rename to samples/client/benchmark/TodayClient.h index 8c0981a9..d0f74413 100644 --- a/samples/client/benchmark/BenchmarkClient.h +++ b/samples/client/benchmark/TodayClient.h @@ -5,8 +5,8 @@ #pragma once -#ifndef BENCHMARKCLIENT_H -#define BENCHMARKCLIENT_H +#ifndef TODAYCLIENT_H +#define TODAYCLIENT_H #include "graphqlservice/GraphQLClient.h" #include "graphqlservice/GraphQLParse.h" @@ -14,6 +14,8 @@ #include "graphqlservice/internal/Version.h" +#include "TodaySchema.h" + #include #include #include @@ -22,7 +24,7 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch"); -namespace graphql::benchmark { +namespace graphql::today { /// # Operation: query (unnamed) /// ```graphql @@ -55,8 +57,8 @@ namespace client { namespace query::Query { -using graphql::benchmark::client::GetRequestText; -using graphql::benchmark::client::GetRequestObject; +using graphql::today::client::GetRequestText; +using graphql::today::client::GetRequestObject; // Return the name of this operation in the shared request document. [[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept; @@ -105,6 +107,6 @@ struct Traits } // namespace query::Query } // namespace client -} // namespace graphql::benchmark +} // namespace graphql::today -#endif // BENCHMARKCLIENT_H +#endif // TODAYCLIENT_H diff --git a/samples/client/benchmark/BenchmarkClient.ixx b/samples/client/benchmark/TodayClient.ixx similarity index 64% rename from samples/client/benchmark/BenchmarkClient.ixx rename to samples/client/benchmark/TodayClient.ixx index 4ab91474..5631ad46 100644 --- a/samples/client/benchmark/BenchmarkClient.ixx +++ b/samples/client/benchmark/TodayClient.ixx @@ -5,11 +5,11 @@ module; -#include "BenchmarkClient.h" +#include "TodayClient.h" -export module GraphQL.Benchmark.BenchmarkClient; +export module GraphQL.Today.TodayClient; -export namespace graphql::benchmark { +export namespace graphql::today { namespace client { @@ -18,8 +18,8 @@ using client::GetRequestObject; namespace query::Query { -using graphql::benchmark::client::GetRequestText; -using graphql::benchmark::client::GetRequestObject; +using graphql::today::client::GetRequestText; +using graphql::today::client::GetRequestObject; using Query::GetOperationName; using Query::Response; @@ -30,4 +30,4 @@ using Query::Traits; } // namespace query::Query } // namespace client -} // namespace graphql::benchmark +} // namespace graphql::today diff --git a/samples/client/benchmark/benchmark_client_files b/samples/client/benchmark/benchmark_client_files index 2d3350f3..995e48c6 100644 --- a/samples/client/benchmark/benchmark_client_files +++ b/samples/client/benchmark/benchmark_client_files @@ -1 +1 @@ -BenchmarkClient.cpp +TodayClient.cpp diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 8dc873ba..69ba95ba 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -1134,7 +1134,8 @@ using namespace )cpp" << _schemaLoader.getSchemaNamespace() sourceFile << R"cpp(template <> response::Value Variable<)cpp" - << cppType << R"cpp(>::serialize()cpp" << cppType << R"cpp(&& inputValue) + << cppType << R"cpp(>::serialize()cpp" << cppType + << R"cpp(&& inputValue) { response::Value result { response::Type::Map }; From 4e0cc8c30e69a7d5a7751ae3ac6f774673110625 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 19 Sep 2024 15:27:22 -0700 Subject: [PATCH 077/123] fix(CI): samples/client/benchmark dir needs module support --- samples/client/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/samples/client/CMakeLists.txt b/samples/client/CMakeLists.txt index 09a6036e..f7a69a70 100644 --- a/samples/client/CMakeLists.txt +++ b/samples/client/CMakeLists.txt @@ -9,10 +9,9 @@ add_subdirectory(subscribe) add_subdirectory(nestedinput) add_subdirectory(multiple) -add_subdirectory(benchmark) - if(GRAPHQL_BUILD_MODULES) # client_benchmark + add_subdirectory(benchmark) add_executable(client_benchmark benchmark.cpp) target_link_libraries(client_benchmark PRIVATE benchmark_client) From 35274d551fb934c1ca99e71a505cdcbdba09b859 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 20 Sep 2024 00:33:09 -0700 Subject: [PATCH 078/123] fix: #297 only require 1 field per Subscription --- include/SchemaGenerator.h | 4 +- samples/learn/CMakeLists.txt | 3 +- samples/learn/StarWarsData.cpp | 5 +- samples/learn/SubscriptionData.cpp | 19 +++ samples/learn/SubscriptionData.h | 29 ++++ samples/learn/schema/StarWarsSchema.cpp | 11 +- samples/learn/schema/StarWarsSchema.h | 12 +- samples/learn/schema/StarWarsSchema.ixx | 2 + samples/learn/schema/SubscriptionObject.cpp | 92 +++++++++++ samples/learn/schema/SubscriptionObject.h | 164 ++++++++++++++++++++ samples/learn/schema/SubscriptionObject.ixx | 16 ++ samples/learn/schema/learn_schema_files | 1 + samples/learn/schema/schema.learn.graphql | 7 +- src/SchemaGenerator.cpp | 101 ++++++------ 14 files changed, 410 insertions(+), 56 deletions(-) create mode 100644 samples/learn/SubscriptionData.cpp create mode 100644 samples/learn/SubscriptionData.h create mode 100644 samples/learn/schema/SubscriptionObject.cpp create mode 100644 samples/learn/schema/SubscriptionObject.h create mode 100644 samples/learn/schema/SubscriptionObject.ixx diff --git a/include/SchemaGenerator.h b/include/SchemaGenerator.h index 225d2b1d..82c1a2b7 100644 --- a/include/SchemaGenerator.h +++ b/include/SchemaGenerator.h @@ -49,8 +49,8 @@ class [[nodiscard("unnecessary construction")]] Generator std::ostream& moduleFile, std::string_view objectNamespace, std::string_view cppType) const; void outputObjectImplements(std::ostream& headerFile, const ObjectType& objectType) const; void outputObjectStubs(std::ostream& headerFile, const ObjectType& objectType) const; - void outputObjectDeclaration( - std::ostream& headerFile, const ObjectType& objectType, bool isQueryType) const; + void outputObjectDeclaration(std::ostream& headerFile, const ObjectType& objectType, + bool isQueryType, bool isSubscriptionType) const; [[nodiscard("unnecessary memory copy")]] std::string getFieldDeclaration( const InputField& inputField) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getFieldDeclaration( diff --git a/samples/learn/CMakeLists.txt b/samples/learn/CMakeLists.txt index 7c0db253..9f718c47 100644 --- a/samples/learn/CMakeLists.txt +++ b/samples/learn/CMakeLists.txt @@ -11,7 +11,8 @@ add_library(star_wars STATIC QueryData.cpp ReviewData.cpp MutationData.cpp - StarWarsData.cpp) + StarWarsData.cpp + SubscriptionData.cpp) target_link_libraries(star_wars PUBLIC learn_schema) target_include_directories(star_wars INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/samples/learn/StarWarsData.cpp b/samples/learn/StarWarsData.cpp index db107051..fcf2397b 100644 --- a/samples/learn/StarWarsData.cpp +++ b/samples/learn/StarWarsData.cpp @@ -8,6 +8,7 @@ #include "MutationData.h" #include "QueryData.h" #include "ReviewData.h" +#include "SubscriptionData.h" using namespace std::literals; @@ -113,7 +114,9 @@ std::shared_ptr GetService() noexcept auto query = std::make_shared(std::move(heroes), std::move(humans), std::move(droids)); auto mutation = std::make_shared(); - auto service = std::make_shared(std::move(query), std::move(mutation)); + auto service = std::make_shared(std::move(query), + std::move(mutation), + std::shared_ptr {}); return service; } diff --git a/samples/learn/SubscriptionData.cpp b/samples/learn/SubscriptionData.cpp new file mode 100644 index 00000000..f100703d --- /dev/null +++ b/samples/learn/SubscriptionData.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "CharacterObject.h" + +#include "SubscriptionData.h" + +namespace graphql::learn { + +Subscription::Subscription() noexcept +{ +} + +std::shared_ptr Subscription::getCharacterChanged() const noexcept +{ + return {}; +} + +} // namespace graphql::learn diff --git a/samples/learn/SubscriptionData.h b/samples/learn/SubscriptionData.h new file mode 100644 index 00000000..1218153d --- /dev/null +++ b/samples/learn/SubscriptionData.h @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#ifndef SUBSCRIPTIONDATA_H +#define SUBSCRIPTIONDATA_H + +#include "SubscriptionObject.h" + +namespace graphql::learn { + +namespace object { + +class Character; + +} // namespace object + +class Subscription +{ +public: + explicit Subscription() noexcept; + + std::shared_ptr getCharacterChanged() const noexcept; +}; + +} // namespace graphql::learn + +#endif // SUBSCRIPTIONDATA_H diff --git a/samples/learn/schema/StarWarsSchema.cpp b/samples/learn/schema/StarWarsSchema.cpp index 5288f5d8..90d252e1 100644 --- a/samples/learn/schema/StarWarsSchema.cpp +++ b/samples/learn/schema/StarWarsSchema.cpp @@ -5,6 +5,7 @@ #include "QueryObject.h" #include "MutationObject.h" +#include "SubscriptionObject.h" #include "graphqlservice/internal/Schema.h" @@ -145,13 +146,15 @@ ReviewInput& ReviewInput::operator=(ReviewInput&& other) noexcept return *this; } -Operations::Operations(std::shared_ptr query, std::shared_ptr mutation) +Operations::Operations(std::shared_ptr query, std::shared_ptr mutation, std::shared_ptr subscription) : service::Request({ { service::strQuery, query }, - { service::strMutation, mutation } + { service::strMutation, mutation }, + { service::strSubscription, subscription } }, GetSchema()) , _query(std::move(query)) , _mutation(std::move(mutation)) + , _subscription(std::move(subscription)) { } @@ -173,6 +176,8 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(Review)gql"sv, typeReview); auto typeMutation = schema::ObjectType::Make(R"gql(Mutation)gql"sv, R"md()md"sv); schema->AddType(R"gql(Mutation)gql"sv, typeMutation); + auto typeSubscription = schema::ObjectType::Make(R"gql(Subscription)gql"sv, R"md()md"sv); + schema->AddType(R"gql(Subscription)gql"sv, typeSubscription); typeEpisode->AddEnumValues({ { service::s_namesEpisode[static_cast(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt }, @@ -192,9 +197,11 @@ void AddTypesToSchema(const std::shared_ptr& schema) AddQueryDetails(typeQuery, schema); AddReviewDetails(typeReview, schema); AddMutationDetails(typeMutation, schema); + AddSubscriptionDetails(typeSubscription, schema); schema->AddQueryType(typeQuery); schema->AddMutationType(typeMutation); + schema->AddSubscriptionType(typeSubscription); } std::shared_ptr GetSchema() diff --git a/samples/learn/schema/StarWarsSchema.h b/samples/learn/schema/StarWarsSchema.h index 6191bfdc..11950217 100644 --- a/samples/learn/schema/StarWarsSchema.h +++ b/samples/learn/schema/StarWarsSchema.h @@ -81,6 +81,7 @@ class Droid; class Query; class Review; class Mutation; +class Subscription; } // namespace object @@ -88,13 +89,14 @@ class [[nodiscard("unnecessary construction")]] Operations final : public service::Request { public: - explicit Operations(std::shared_ptr query, std::shared_ptr mutation); + explicit Operations(std::shared_ptr query, std::shared_ptr mutation, std::shared_ptr subscription); - template - explicit Operations(std::shared_ptr query, std::shared_ptr mutation) + template + explicit Operations(std::shared_ptr query, std::shared_ptr mutation, std::shared_ptr subscription = {}) : Operations { std::make_shared(std::move(query)), - std::make_shared(std::move(mutation)) + std::make_shared(std::move(mutation)), + subscription ? std::make_shared(std::move(subscription)) : std::shared_ptr {} } { } @@ -102,6 +104,7 @@ class [[nodiscard("unnecessary construction")]] Operations final private: std::shared_ptr _query; std::shared_ptr _mutation; + std::shared_ptr _subscription; }; void AddCharacterDetails(const std::shared_ptr& typeCharacter, const std::shared_ptr& schema); @@ -111,6 +114,7 @@ void AddDroidDetails(const std::shared_ptr& typeDroid, const void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema); void AddReviewDetails(const std::shared_ptr& typeReview, const std::shared_ptr& schema); void AddMutationDetails(const std::shared_ptr& typeMutation, const std::shared_ptr& schema); +void AddSubscriptionDetails(const std::shared_ptr& typeSubscription, const std::shared_ptr& schema); std::shared_ptr GetSchema(); diff --git a/samples/learn/schema/StarWarsSchema.ixx b/samples/learn/schema/StarWarsSchema.ixx index 45885809..1a339c7c 100644 --- a/samples/learn/schema/StarWarsSchema.ixx +++ b/samples/learn/schema/StarWarsSchema.ixx @@ -15,6 +15,7 @@ export import GraphQL.StarWars.DroidObject; export import GraphQL.StarWars.QueryObject; export import GraphQL.StarWars.ReviewObject; export import GraphQL.StarWars.MutationObject; +export import GraphQL.StarWars.SubscriptionObject; export namespace graphql::learn { @@ -32,6 +33,7 @@ using learn::AddDroidDetails; using learn::AddQueryDetails; using learn::AddReviewDetails; using learn::AddMutationDetails; +using learn::AddSubscriptionDetails; using learn::GetSchema; diff --git a/samples/learn/schema/SubscriptionObject.cpp b/samples/learn/schema/SubscriptionObject.cpp new file mode 100644 index 00000000..96f204f6 --- /dev/null +++ b/samples/learn/schema/SubscriptionObject.cpp @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#include "SubscriptionObject.h" +#include "CharacterObject.h" + +#include "graphqlservice/internal/Schema.h" + +#include "graphqlservice/introspection/IntrospectionSchema.h" + +#include +#include +#include +#include + +using namespace std::literals; + +namespace graphql::learn { +namespace object { + +Subscription::Subscription(std::unique_ptr pimpl) noexcept + : service::Object{ getTypeNames(), getResolvers() } + , _pimpl { std::move(pimpl) } +{ +} + +service::TypeNames Subscription::getTypeNames() const noexcept +{ + return { + R"gql(Subscription)gql"sv + }; +} + +service::ResolverMap Subscription::getResolvers() const noexcept +{ + return { + { R"gql(__typename)gql"sv, [this](service::ResolverParams&& params) { return resolve_typename(std::move(params)); } }, + { R"gql(newEpisode)gql"sv, [this](service::ResolverParams&& params) { return resolveNewEpisode(std::move(params)); } }, + { R"gql(characterChanged)gql"sv, [this](service::ResolverParams&& params) { return resolveCharacterChanged(std::move(params)); } } + }; +} + +void Subscription::beginSelectionSet(const service::SelectionSetParams& params) const +{ + _pimpl->beginSelectionSet(params); +} + +void Subscription::endSelectionSet(const service::SelectionSetParams& params) const +{ + _pimpl->endSelectionSet(params); +} + +service::AwaitableResolver Subscription::resolveCharacterChanged(service::ResolverParams&& params) const +{ + std::unique_lock resolverLock(_resolverMutex); + service::SelectionSetParams selectionSetParams { static_cast(params) }; + auto directives = std::move(params.fieldDirectives); + auto result = _pimpl->getCharacterChanged(service::FieldParams { std::move(selectionSetParams), std::move(directives) }); + resolverLock.unlock(); + + return service::ModifiedResult::convert(std::move(result), std::move(params)); +} + +service::AwaitableResolver Subscription::resolveNewEpisode(service::ResolverParams&& params) const +{ + std::unique_lock resolverLock(_resolverMutex); + service::SelectionSetParams selectionSetParams { static_cast(params) }; + auto directives = std::move(params.fieldDirectives); + auto result = _pimpl->getNewEpisode(service::FieldParams { std::move(selectionSetParams), std::move(directives) }); + resolverLock.unlock(); + + return service::ModifiedResult::convert(std::move(result), std::move(params)); +} + +service::AwaitableResolver Subscription::resolve_typename(service::ResolverParams&& params) const +{ + return service::Result::convert(std::string{ R"gql(Subscription)gql" }, std::move(params)); +} + +} // namespace object + +void AddSubscriptionDetails(const std::shared_ptr& typeSubscription, const std::shared_ptr& schema) +{ + typeSubscription->AddFields({ + schema::Field::Make(R"gql(characterChanged)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(Character)gql"sv))), + schema::Field::Make(R"gql(newEpisode)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(Episode)gql"sv))) + }); +} + +} // namespace graphql::learn diff --git a/samples/learn/schema/SubscriptionObject.h b/samples/learn/schema/SubscriptionObject.h new file mode 100644 index 00000000..958211fa --- /dev/null +++ b/samples/learn/schema/SubscriptionObject.h @@ -0,0 +1,164 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef SUBSCRIPTIONOBJECT_H +#define SUBSCRIPTIONOBJECT_H + +#include "StarWarsSchema.h" + +namespace graphql::learn::object { +namespace methods::SubscriptionHas { + +template +concept getCharacterChangedWithParams = requires (TImpl impl, service::FieldParams params) +{ + { service::AwaitableObject> { impl.getCharacterChanged(std::move(params)) } }; +}; + +template +concept getCharacterChanged = requires (TImpl impl) +{ + { service::AwaitableObject> { impl.getCharacterChanged() } }; +}; + +template +concept getNewEpisodeWithParams = requires (TImpl impl, service::FieldParams params) +{ + { service::AwaitableScalar { impl.getNewEpisode(std::move(params)) } }; +}; + +template +concept getNewEpisode = requires (TImpl impl) +{ + { service::AwaitableScalar { impl.getNewEpisode() } }; +}; + +template +concept beginSelectionSet = requires (TImpl impl, const service::SelectionSetParams params) +{ + { impl.beginSelectionSet(params) }; +}; + +template +concept endSelectionSet = requires (TImpl impl, const service::SelectionSetParams params) +{ + { impl.endSelectionSet(params) }; +}; + +} // namespace methods::SubscriptionHas + +class [[nodiscard("unnecessary construction")]] Subscription final + : public service::Object +{ +private: + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveCharacterChanged(service::ResolverParams&& params) const; + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveNewEpisode(service::ResolverParams&& params) const; + + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolve_typename(service::ResolverParams&& params) const; + + struct [[nodiscard("unnecessary construction")]] Concept + { + virtual ~Concept() = default; + + virtual void beginSelectionSet(const service::SelectionSetParams& params) const = 0; + virtual void endSelectionSet(const service::SelectionSetParams& params) const = 0; + + [[nodiscard("unnecessary call")]] virtual service::AwaitableObject> getCharacterChanged(service::FieldParams&& params) const = 0; + [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar getNewEpisode(service::FieldParams&& params) const = 0; + }; + + template + struct [[nodiscard("unnecessary construction")]] Model final + : Concept + { + explicit Model(std::shared_ptr pimpl) noexcept + : _pimpl { std::move(pimpl) } + { + static_assert(methods::SubscriptionHas::getCharacterChangedWithParams + || methods::SubscriptionHas::getCharacterChanged + || methods::SubscriptionHas::getNewEpisodeWithParams + || methods::SubscriptionHas::getNewEpisode, R"msg(Subscription fields are not implemented)msg"); + } + + [[nodiscard("unnecessary call")]] service::AwaitableObject> getCharacterChanged(service::FieldParams&& params) const override + { + if constexpr (methods::SubscriptionHas::getCharacterChangedWithParams) + { + return { _pimpl->getCharacterChanged(std::move(params)) }; + } + else if constexpr (methods::SubscriptionHas::getCharacterChanged) + { + return { _pimpl->getCharacterChanged() }; + } + else + { + throw service::unimplemented_method(R"ex(Subscription::getCharacterChanged)ex"); + } + } + + [[nodiscard("unnecessary call")]] service::AwaitableScalar getNewEpisode(service::FieldParams&& params) const override + { + if constexpr (methods::SubscriptionHas::getNewEpisodeWithParams) + { + return { _pimpl->getNewEpisode(std::move(params)) }; + } + else if constexpr (methods::SubscriptionHas::getNewEpisode) + { + return { _pimpl->getNewEpisode() }; + } + else + { + throw service::unimplemented_method(R"ex(Subscription::getNewEpisode)ex"); + } + } + + void beginSelectionSet(const service::SelectionSetParams& params) const override + { + if constexpr (methods::SubscriptionHas::beginSelectionSet) + { + _pimpl->beginSelectionSet(params); + } + } + + void endSelectionSet(const service::SelectionSetParams& params) const override + { + if constexpr (methods::SubscriptionHas::endSelectionSet) + { + _pimpl->endSelectionSet(params); + } + } + + private: + const std::shared_ptr _pimpl; + }; + + explicit Subscription(std::unique_ptr pimpl) noexcept; + + [[nodiscard("unnecessary call")]] service::TypeNames getTypeNames() const noexcept; + [[nodiscard("unnecessary call")]] service::ResolverMap getResolvers() const noexcept; + + void beginSelectionSet(const service::SelectionSetParams& params) const override; + void endSelectionSet(const service::SelectionSetParams& params) const override; + + const std::unique_ptr _pimpl; + +public: + template + explicit Subscription(std::shared_ptr pimpl) noexcept + : Subscription { std::unique_ptr { std::make_unique>(std::move(pimpl)) } } + { + } + + [[nodiscard("unnecessary call")]] static constexpr std::string_view getObjectType() noexcept + { + return { R"gql(Subscription)gql" }; + } +}; + +} // namespace graphql::learn::object + +#endif // SUBSCRIPTIONOBJECT_H diff --git a/samples/learn/schema/SubscriptionObject.ixx b/samples/learn/schema/SubscriptionObject.ixx new file mode 100644 index 00000000..2e3178ae --- /dev/null +++ b/samples/learn/schema/SubscriptionObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SubscriptionObject.h" + +export module GraphQL.StarWars.SubscriptionObject; + +export namespace graphql::learn::object { + +using object::Subscription; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/learn_schema_files b/samples/learn/schema/learn_schema_files index 4f897e53..3b3fc41b 100644 --- a/samples/learn/schema/learn_schema_files +++ b/samples/learn/schema/learn_schema_files @@ -5,3 +5,4 @@ DroidObject.cpp QueryObject.cpp ReviewObject.cpp MutationObject.cpp +SubscriptionObject.cpp diff --git a/samples/learn/schema/schema.learn.graphql b/samples/learn/schema/schema.learn.graphql index 694955be..1670aa49 100644 --- a/samples/learn/schema/schema.learn.graphql +++ b/samples/learn/schema/schema.learn.graphql @@ -44,4 +44,9 @@ type Review { type Mutation { createReview(ep: Episode! review: ReviewInput!): Review! -} \ No newline at end of file +} + +type Subscription { + characterChanged: Character! + newEpisode: Episode! +} diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index eda453eb..7bf1af1d 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -157,20 +157,6 @@ static_assert(graphql::internal::MinorVersion == )cpp" NamespaceScope objectNamespace { headerFile, "object", true }; PendingBlankLine pendingSeparator { headerFile }; - std::string_view queryType; - - if (!_loader.isIntrospection()) - { - for (const auto& operation : _loader.getOperationTypes()) - { - if (operation.operation == service::strQuery) - { - queryType = operation.type; - break; - } - } - } - if (!_loader.getEnumTypes().empty()) { pendingSeparator.reset(); @@ -1069,8 +1055,8 @@ concept endSelectionSet = requires (TImpl impl, const service::SelectionSetParam )cpp"; } -void Generator::outputObjectDeclaration( - std::ostream& headerFile, const ObjectType& objectType, bool isQueryType) const +void Generator::outputObjectDeclaration(std::ostream& headerFile, const ObjectType& objectType, + bool isQueryType, bool isSubscriptionType) const { headerFile << R"cpp(class [[nodiscard("unnecessary construction")]] )cpp" << objectType.cppType << R"cpp( final @@ -1128,7 +1114,37 @@ void Generator::outputObjectDeclaration( explicit Model(std::shared_ptr pimpl) noexcept : _pimpl { std::move(pimpl) } { +)cpp"; + + if (isSubscriptionType && !_options.stubs) + { + headerFile << R"cpp( static_assert()cpp"; + + bool firstField = true; + + for (const auto& outputField : objectType.fields) + { + const auto accessorName = SchemaLoader::getOutputCppAccessor(outputField); + + if (!firstField) + { + headerFile << R"cpp( + || )cpp"; + } + + firstField = false; + headerFile << R"cpp(methods::)cpp" << objectType.cppType << R"cpp(Has::)cpp" + << accessorName << R"cpp(WithParams + || methods::)cpp" + << objectType.cppType << R"cpp(Has::)cpp" << accessorName << R"cpp()cpp"; } + + headerFile << R"cpp(, R"msg()cpp" << objectType.cppType + << R"cpp( fields are not implemented)msg"); +)cpp"; + } + + headerFile << R"cpp( } )cpp"; for (const auto& outputField : objectType.fields) @@ -1207,7 +1223,7 @@ void Generator::outputObjectDeclaration( } else)cpp"; - if (!_options.stubs) + if (!isSubscriptionType && !_options.stubs) { headerFile << R"cpp( { @@ -1235,7 +1251,7 @@ void Generator::outputObjectDeclaration( headerFile << R"cpp() }; })cpp"; - if (_options.stubs) + if (isSubscriptionType || _options.stubs) { headerFile << R"cpp( else @@ -1680,7 +1696,6 @@ void Result<)cpp" << _loader.getSchemaNamespace() } NamespaceScope schemaNamespace { sourceFile, _loader.getSchemaNamespace() }; - std::string_view queryType; for (const auto& inputType : _loader.getInputTypes()) { @@ -1846,18 +1861,6 @@ void Result<)cpp" << _loader.getSchemaNamespace() )cpp"; } - if (!_loader.isIntrospection()) - { - for (const auto& operation : _loader.getOperationTypes()) - { - if (operation.operation == service::strQuery) - { - queryType = operation.type; - break; - } - } - } - if (!_loader.isIntrospection()) { bool firstOperation = true; @@ -2289,8 +2292,7 @@ Operations::Operations()cpp"; )cpp"; } sourceFile << R"cpp(}, )cpp" - << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") - << R"cpp()); + << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") << R"cpp()); )cpp"; } } @@ -3208,16 +3210,6 @@ std::vector Generator::outputSeparateFiles() const noexcept const std::filesystem::path headerDir(_headerDir); const std::filesystem::path sourceDir(_sourceDir); std::vector files; - std::string_view queryType; - - for (const auto& operation : _loader.getOperationTypes()) - { - if (operation.operation == service::strQuery) - { - queryType = operation.type; - break; - } - } const auto schemaNamespace = std::format(R"cpp(graphql::{})cpp", _loader.getSchemaNamespace()); const auto objectNamespace = std::format(R"cpp({}::object)cpp", schemaNamespace); @@ -3392,7 +3384,26 @@ using namespace std::literals; for (const auto& objectType : _loader.getObjectTypes()) { - const bool isQueryType = objectType.type == queryType; + bool isQueryType = false; + bool isSubscriptionType = false; + + for (const auto& operation : _loader.getOperationTypes()) + { + if (objectType.type == operation.type) + { + if (operation.operation == service::strQuery) + { + isQueryType = true; + } + else if (operation.operation == service::strSubscription) + { + isSubscriptionType = true; + } + + break; + } + } + const auto headerFilename = std::string(objectType.cppType) + "Object.h"; auto headerPath = (headerDir / headerFilename).string(); @@ -3430,7 +3441,7 @@ using namespace std::literals; // Output the full declaration headerFile << std::endl; - outputObjectDeclaration(headerFile, objectType, isQueryType); + outputObjectDeclaration(headerFile, objectType, isQueryType, isSubscriptionType); headerFile << std::endl; } From 29c3c83fa14dd6f4ea91871d1f8d203f0ba9e3cd Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 20 Sep 2024 16:39:07 -0700 Subject: [PATCH 079/123] feat(sharedtypes): implement simpler update_graphql_shared_client_files --- cmake/cppgraphqlgen-functions.cmake | 61 +++++++++++++++++++++++-- samples/CMakeLists.txt | 8 ++-- samples/client/CMakeLists.txt | 1 + samples/client/benchmark/CMakeLists.txt | 3 +- samples/proxy/CMakeLists.txt | 2 +- samples/proxy/query/CMakeLists.txt | 3 +- 6 files changed, 64 insertions(+), 14 deletions(-) diff --git a/cmake/cppgraphqlgen-functions.cmake b/cmake/cppgraphqlgen-functions.cmake index f17a1ff0..fad90e0c 100644 --- a/cmake/cppgraphqlgen-functions.cmake +++ b/cmake/cppgraphqlgen-functions.cmake @@ -36,16 +36,23 @@ function(update_graphql_schema_files SCHEMA_TARGET SCHEMA_GRAPHQL SCHEMA_PREFIX DEPENDS ${SCHEMA_GRAPHQL} ${GRAPHQL_UPDATE_SCHEMA_FILES_SCRIPT} cppgraphqlgen::schemagen COMMENT "Generating ${SCHEMA_TARGET} GraphQL schema" VERBATIM) -endfunction() -function(add_graphql_schema_target SCHEMA_TARGET) add_custom_target(${SCHEMA_TARGET}_update_schema ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_TARGET}_schema_files) + file(REAL_PATH ${SCHEMA_GRAPHQL} SCHEMA_GRAPHQL BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set_target_properties(${SCHEMA_TARGET}_update_schema PROPERTIES + SCHEMA_GRAPHQL ${SCHEMA_GRAPHQL} + SCHEMA_PREFIX ${SCHEMA_PREFIX} + SCHEMA_NAMESPACE ${SCHEMA_NAMESPACE}) +endfunction() +function(add_graphql_schema_target SCHEMA_TARGET) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_TARGET}_schema_files) file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_TARGET}_schema_files SCHEMA_FILES) add_library(${SCHEMA_TARGET}_schema STATIC ${SCHEMA_FILES}) - add_dependencies(${SCHEMA_TARGET}_schema ${SCHEMA_TARGET}_update_schema) + if(TARGET ${SCHEMA_TARGET}_update_schema) + add_dependencies(${SCHEMA_TARGET}_schema ${SCHEMA_TARGET}_update_schema) + endif() target_compile_features(${SCHEMA_TARGET}_schema PUBLIC cxx_std_20) target_include_directories(${SCHEMA_TARGET}_schema PUBLIC $) target_link_libraries(${SCHEMA_TARGET}_schema PUBLIC cppgraphqlgen::graphqlservice) @@ -90,19 +97,63 @@ function(update_graphql_client_files CLIENT_TARGET SCHEMA_GRAPHQL REQUEST_GRAPHQ DEPENDS ${SCHEMA_GRAPHQL} ${REQUEST_GRAPHQL} ${GRAPHQL_UPDATE_CLIENT_FILES_SCRIPT} cppgraphqlgen::clientgen COMMENT "Generating ${CLIENT_TARGET} client" VERBATIM) + + add_custom_target(${CLIENT_TARGET}_update_client ALL + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${CLIENT_TARGET}_client_files) endfunction() -function(add_graphql_client_target CLIENT_TARGET) +function(update_graphql_shared_client_files CLIENT_TARGET SCHEMA_TARGET REQUEST_GRAPHQL) + set_property(DIRECTORY APPEND + PROPERTY CMAKE_CONFIGURE_DEPENDS ${CLIENT_TARGET}_client_files) + get_target_property(SCHEMA_GRAPHQL ${SCHEMA_TARGET}_update_schema SCHEMA_GRAPHQL) + file(RELATIVE_PATH SCHEMA_GRAPHQL ${CMAKE_CURRENT_SOURCE_DIR} ${SCHEMA_GRAPHQL}) + get_target_property(SCHEMA_PREFIX ${SCHEMA_TARGET}_update_schema SCHEMA_PREFIX) + get_target_property(SCHEMA_NAMESPACE ${SCHEMA_TARGET}_update_schema SCHEMA_NAMESPACE) + + # Collect optional arguments + set(ADDITIONAL_CLIENTGEN_ARGS "--shared-types") + if(ARGC GREATER 4) + math(EXPR LAST_ARG "${ARGC} - 1") + foreach(ARGN RANGE 4 ${LAST_ARG}) + set(NEXT_ARG "${ARGV${ARGN}}") + list(APPEND ADDITIONAL_CLIENTGEN_ARGS "${NEXT_ARG}") + endforeach() + endif() + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${CLIENT_TARGET}_client_files + COMMAND + ${CMAKE_COMMAND} "-DCLIENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}" + "-DCLIENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}" + "-DCLIENTGEN_PROGRAM=$" "-DCLIENT_TARGET=${CLIENT_TARGET}" + "-DSCHEMA_GRAPHQL=${SCHEMA_GRAPHQL}" "-DREQUEST_GRAPHQL=${REQUEST_GRAPHQL}" + "-DCLIENT_PREFIX=${SCHEMA_PREFIX}" "-DCLIENT_NAMESPACE=${SCHEMA_NAMESPACE}" + "-DADDITIONAL_CLIENTGEN_ARGS=${ADDITIONAL_CLIENTGEN_ARGS}" + -P ${GRAPHQL_UPDATE_CLIENT_FILES_SCRIPT} + DEPENDS ${SCHEMA_GRAPHQL} ${REQUEST_GRAPHQL} ${GRAPHQL_UPDATE_CLIENT_FILES_SCRIPT} cppgraphqlgen::clientgen + COMMENT "Generating ${CLIENT_TARGET} client" + VERBATIM) + add_custom_target(${CLIENT_TARGET}_update_client ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${CLIENT_TARGET}_client_files) + set_target_properties(${CLIENT_TARGET}_update_client PROPERTIES + SCHEMA_TARGET ${SCHEMA_TARGET}) +endfunction() +function(add_graphql_client_target CLIENT_TARGET) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${CLIENT_TARGET}_client_files) file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${CLIENT_TARGET}_client_files CLIENT_FILES) add_library(${CLIENT_TARGET}_client STATIC ${CLIENT_FILES}) - add_dependencies(${CLIENT_TARGET}_client ${CLIENT_TARGET}_update_client) + if(TARGET ${CLIENT_TARGET}_update_client) + add_dependencies(${CLIENT_TARGET}_client ${CLIENT_TARGET}_update_client) + endif() target_compile_features(${CLIENT_TARGET}_client PUBLIC cxx_std_20) target_include_directories(${CLIENT_TARGET}_client PUBLIC $) target_link_libraries(${CLIENT_TARGET}_client PUBLIC cppgraphqlgen::graphqlclient) + get_target_property(SCHEMA_TARGET ${CLIENT_TARGET}_update_client SCHEMA_TARGET) + if(SCHEMA_TARGET) + target_link_libraries(${CLIENT_TARGET}_client PUBLIC ${SCHEMA_TARGET}_schema) + endif() file(GLOB CLIENT_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) target_sources(${CLIENT_TARGET}_client PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index e3a2b1fd..c0f54513 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -3,14 +3,14 @@ cmake_minimum_required(VERSION 3.28) -add_subdirectory(client) -add_subdirectory(learn) -add_subdirectory(validation) - if(GRAPHQL_BUILD_MODULES) add_subdirectory(today) endif() +add_subdirectory(client) +add_subdirectory(learn) +add_subdirectory(validation) + if(GRAPHQL_BUILD_HTTP_SAMPLE) find_package(boost_beast CONFIG QUIET) if(boost_beast_FOUND) diff --git a/samples/client/CMakeLists.txt b/samples/client/CMakeLists.txt index f7a69a70..1962dc7e 100644 --- a/samples/client/CMakeLists.txt +++ b/samples/client/CMakeLists.txt @@ -14,6 +14,7 @@ if(GRAPHQL_BUILD_MODULES) add_subdirectory(benchmark) add_executable(client_benchmark benchmark.cpp) target_link_libraries(client_benchmark PRIVATE + todaygraphql benchmark_client) if(WIN32 AND BUILD_SHARED_LIBS) diff --git a/samples/client/benchmark/CMakeLists.txt b/samples/client/benchmark/CMakeLists.txt index dc132942..7679664f 100644 --- a/samples/client/benchmark/CMakeLists.txt +++ b/samples/client/benchmark/CMakeLists.txt @@ -7,8 +7,7 @@ cmake_minimum_required(VERSION 3.28) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) if(GRAPHQL_UPDATE_SAMPLES AND GRAPHQL_BUILD_CLIENTGEN) - update_graphql_client_files(benchmark ../../today/schema.today.graphql client.benchmark.today.graphql Today today --shared-types) + update_graphql_shared_client_files(benchmark today client.benchmark.today.graphql) endif() add_graphql_client_target(benchmark) -target_link_libraries(benchmark_client PRIVATE todaygraphql) diff --git a/samples/proxy/CMakeLists.txt b/samples/proxy/CMakeLists.txt index e518aca8..5b70f5b0 100644 --- a/samples/proxy/CMakeLists.txt +++ b/samples/proxy/CMakeLists.txt @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.28) -add_subdirectory(query) add_subdirectory(schema) +add_subdirectory(query) add_executable(client client.cpp) target_link_libraries(client PRIVATE diff --git a/samples/proxy/query/CMakeLists.txt b/samples/proxy/query/CMakeLists.txt index 8c4fcdb0..f7ae51ab 100644 --- a/samples/proxy/query/CMakeLists.txt +++ b/samples/proxy/query/CMakeLists.txt @@ -7,8 +7,7 @@ cmake_minimum_required(VERSION 3.28) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) if(GRAPHQL_UPDATE_SAMPLES AND GRAPHQL_BUILD_CLIENTGEN) - update_graphql_client_files(proxy ../schema/schema.graphql query.graphql Proxy proxy --shared-types) + update_graphql_shared_client_files(proxy proxy query.graphql) endif() add_graphql_client_target(proxy) -target_link_libraries(proxy_client PRIVATE proxy_schema) \ No newline at end of file From 0e5ded2f230dc431a771ff1bc89ebcd5b0fdc8bc Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 23 Sep 2024 21:22:47 -0700 Subject: [PATCH 080/123] fix: #321 --- cmake/cppgraphqlgen-update-schema-files.cmake | 4 +- include/SchemaGenerator.h | 18 +- .../introspection/IntrospectionSchema.h | 124 +--- .../introspection/IntrospectionSchema.ixx | 10 +- .../introspection/IntrospectionSharedTypes.h | 151 ++++ .../IntrospectionSharedTypes.ixx | 22 + samples/learn/schema/StarWarsSchema.h | 49 +- samples/learn/schema/StarWarsSchema.ixx | 8 +- samples/learn/schema/StarWarsSharedTypes.h | 76 +++ samples/learn/schema/StarWarsSharedTypes.ixx | 20 + samples/proxy/schema/ProxySchema.h | 53 +- samples/proxy/schema/ProxySchema.ixx | 8 +- samples/proxy/schema/ProxySharedTypes.h | 80 +++ samples/proxy/schema/ProxySharedTypes.ixx | 20 + samples/today/nointrospection/TodaySchema.h | 210 +----- samples/today/nointrospection/TodaySchema.ixx | 16 +- .../today/nointrospection/TodaySharedTypes.h | 237 +++++++ .../nointrospection/TodaySharedTypes.ixx | 28 + samples/today/schema/TodaySchema.h | 210 +----- samples/today/schema/TodaySchema.ixx | 16 +- samples/today/schema/TodaySharedTypes.h | 237 +++++++ samples/today/schema/TodaySharedTypes.ixx | 28 + samples/validation/schema/ValidationSchema.h | 72 +- .../validation/schema/ValidationSchema.ixx | 12 +- .../validation/schema/ValidationSharedTypes.h | 99 +++ .../schema/ValidationSharedTypes.ixx | 24 + src/SchemaGenerator.cpp | 643 +++++++++++------- src/introspection/IntrospectionSchema.h | 124 +--- src/introspection/IntrospectionSchema.ixx | 10 +- src/introspection/IntrospectionSharedTypes.h | 151 ++++ .../IntrospectionSharedTypes.ixx | 22 + 31 files changed, 1623 insertions(+), 1159 deletions(-) create mode 100644 include/graphqlservice/introspection/IntrospectionSharedTypes.h create mode 100644 include/graphqlservice/introspection/IntrospectionSharedTypes.ixx create mode 100644 samples/learn/schema/StarWarsSharedTypes.h create mode 100644 samples/learn/schema/StarWarsSharedTypes.ixx create mode 100644 samples/proxy/schema/ProxySharedTypes.h create mode 100644 samples/proxy/schema/ProxySharedTypes.ixx create mode 100644 samples/today/nointrospection/TodaySharedTypes.h create mode 100644 samples/today/nointrospection/TodaySharedTypes.ixx create mode 100644 samples/today/schema/TodaySharedTypes.h create mode 100644 samples/today/schema/TodaySharedTypes.ixx create mode 100644 samples/validation/schema/ValidationSharedTypes.h create mode 100644 samples/validation/schema/ValidationSharedTypes.ixx create mode 100644 src/introspection/IntrospectionSharedTypes.h create mode 100644 src/introspection/IntrospectionSharedTypes.ixx diff --git a/cmake/cppgraphqlgen-update-schema-files.cmake b/cmake/cppgraphqlgen-update-schema-files.cmake index 8955f6fd..5ca5c55e 100644 --- a/cmake/cppgraphqlgen-update-schema-files.cmake +++ b/cmake/cppgraphqlgen-update-schema-files.cmake @@ -52,7 +52,9 @@ foreach(OLD_FILE ${OLD_FILES}) file(REMOVE "${SCHEMA_SOURCE_DIR}/${OLD_FILE}") elseif(NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.h" AND NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.ixx" AND - NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.cpp") + NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.cpp" AND + NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}SharedTypes.h" AND + NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}SharedTypes.ixx") message(WARNING "Unexpected file in ${SCHEMA_TARGET} GraphQL schema sources: ${OLD_FILE}") endif() endif() diff --git a/include/SchemaGenerator.h b/include/SchemaGenerator.h index 82c1a2b7..8a7b54bb 100644 --- a/include/SchemaGenerator.h +++ b/include/SchemaGenerator.h @@ -38,12 +38,16 @@ class [[nodiscard("unnecessary construction")]] Generator private: [[nodiscard("unnecessary memory copy")]] std::string getHeaderDir() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSourceDir() const noexcept; - [[nodiscard("unnecessary memory copy")]] std::string getHeaderPath() const noexcept; - [[nodiscard("unnecessary memory copy")]] std::string getModulePath() const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getSchemaHeaderPath() const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getSchemaModulePath() const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getSharedTypesHeaderPath() const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getSharedTypesModulePath() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSourcePath() const noexcept; - [[nodiscard("unnecessary call")]] bool outputHeader() const noexcept; - [[nodiscard("unnecessary call")]] bool outputModule() const noexcept; + [[nodiscard("unnecessary call")]] bool outputSchemaHeader() const noexcept; + [[nodiscard("unnecessary call")]] bool outputSchemaModule() const noexcept; + [[nodiscard("unnecessary call")]] bool outputSharedTypesHeader() const noexcept; + [[nodiscard("unnecessary call")]] bool outputSharedTypesModule() const noexcept; void outputInterfaceDeclaration(std::ostream& headerFile, std::string_view cppType) const; void outputObjectModule( std::ostream& moduleFile, std::string_view objectNamespace, std::string_view cppType) const; @@ -94,8 +98,10 @@ class [[nodiscard("unnecessary construction")]] Generator const std::string _headerDir; const std::string _moduleDir; const std::string _sourceDir; - const std::string _headerPath; - const std::string _modulePath; + const std::string _schemaHeaderPath; + const std::string _schemaModulePath; + const std::string _sharedTypesHeaderPath; + const std::string _sharedTypesModulePath; const std::string _sourcePath; }; diff --git a/include/graphqlservice/introspection/IntrospectionSchema.h b/include/graphqlservice/introspection/IntrospectionSchema.h index b754e4ad..3ea811b0 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.h +++ b/include/graphqlservice/introspection/IntrospectionSchema.h @@ -14,6 +14,8 @@ #include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" +#include "IntrospectionSharedTypes.h" + #include #include #include @@ -25,128 +27,6 @@ static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: namespace graphql { namespace introspection { - -enum class TypeKind -{ - SCALAR, - OBJECT, - INTERFACE, - UNION, - ENUM, - INPUT_OBJECT, - LIST, - NON_NULL -}; - -[[nodiscard("unnecessary call")]] constexpr auto getTypeKindNames() noexcept -{ - using namespace std::literals; - - return std::array { - R"gql(SCALAR)gql"sv, - R"gql(OBJECT)gql"sv, - R"gql(INTERFACE)gql"sv, - R"gql(UNION)gql"sv, - R"gql(ENUM)gql"sv, - R"gql(INPUT_OBJECT)gql"sv, - R"gql(LIST)gql"sv, - R"gql(NON_NULL)gql"sv - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto getTypeKindValues() noexcept -{ - using namespace std::literals; - - return std::array, 8> { - std::make_pair(R"gql(ENUM)gql"sv, TypeKind::ENUM), - std::make_pair(R"gql(LIST)gql"sv, TypeKind::LIST), - std::make_pair(R"gql(UNION)gql"sv, TypeKind::UNION), - std::make_pair(R"gql(OBJECT)gql"sv, TypeKind::OBJECT), - std::make_pair(R"gql(SCALAR)gql"sv, TypeKind::SCALAR), - std::make_pair(R"gql(NON_NULL)gql"sv, TypeKind::NON_NULL), - std::make_pair(R"gql(INTERFACE)gql"sv, TypeKind::INTERFACE), - std::make_pair(R"gql(INPUT_OBJECT)gql"sv, TypeKind::INPUT_OBJECT) - }; -} - -enum class DirectiveLocation -{ - QUERY, - MUTATION, - SUBSCRIPTION, - FIELD, - FRAGMENT_DEFINITION, - FRAGMENT_SPREAD, - INLINE_FRAGMENT, - VARIABLE_DEFINITION, - SCHEMA, - SCALAR, - OBJECT, - FIELD_DEFINITION, - ARGUMENT_DEFINITION, - INTERFACE, - UNION, - ENUM, - ENUM_VALUE, - INPUT_OBJECT, - INPUT_FIELD_DEFINITION -}; - -[[nodiscard("unnecessary call")]] constexpr auto getDirectiveLocationNames() noexcept -{ - using namespace std::literals; - - return std::array { - R"gql(QUERY)gql"sv, - R"gql(MUTATION)gql"sv, - R"gql(SUBSCRIPTION)gql"sv, - R"gql(FIELD)gql"sv, - R"gql(FRAGMENT_DEFINITION)gql"sv, - R"gql(FRAGMENT_SPREAD)gql"sv, - R"gql(INLINE_FRAGMENT)gql"sv, - R"gql(VARIABLE_DEFINITION)gql"sv, - R"gql(SCHEMA)gql"sv, - R"gql(SCALAR)gql"sv, - R"gql(OBJECT)gql"sv, - R"gql(FIELD_DEFINITION)gql"sv, - R"gql(ARGUMENT_DEFINITION)gql"sv, - R"gql(INTERFACE)gql"sv, - R"gql(UNION)gql"sv, - R"gql(ENUM)gql"sv, - R"gql(ENUM_VALUE)gql"sv, - R"gql(INPUT_OBJECT)gql"sv, - R"gql(INPUT_FIELD_DEFINITION)gql"sv - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto getDirectiveLocationValues() noexcept -{ - using namespace std::literals; - - return std::array, 19> { - std::make_pair(R"gql(ENUM)gql"sv, DirectiveLocation::ENUM), - std::make_pair(R"gql(FIELD)gql"sv, DirectiveLocation::FIELD), - std::make_pair(R"gql(QUERY)gql"sv, DirectiveLocation::QUERY), - std::make_pair(R"gql(UNION)gql"sv, DirectiveLocation::UNION), - std::make_pair(R"gql(OBJECT)gql"sv, DirectiveLocation::OBJECT), - std::make_pair(R"gql(SCALAR)gql"sv, DirectiveLocation::SCALAR), - std::make_pair(R"gql(SCHEMA)gql"sv, DirectiveLocation::SCHEMA), - std::make_pair(R"gql(MUTATION)gql"sv, DirectiveLocation::MUTATION), - std::make_pair(R"gql(INTERFACE)gql"sv, DirectiveLocation::INTERFACE), - std::make_pair(R"gql(ENUM_VALUE)gql"sv, DirectiveLocation::ENUM_VALUE), - std::make_pair(R"gql(INPUT_OBJECT)gql"sv, DirectiveLocation::INPUT_OBJECT), - std::make_pair(R"gql(SUBSCRIPTION)gql"sv, DirectiveLocation::SUBSCRIPTION), - std::make_pair(R"gql(FRAGMENT_SPREAD)gql"sv, DirectiveLocation::FRAGMENT_SPREAD), - std::make_pair(R"gql(INLINE_FRAGMENT)gql"sv, DirectiveLocation::INLINE_FRAGMENT), - std::make_pair(R"gql(FIELD_DEFINITION)gql"sv, DirectiveLocation::FIELD_DEFINITION), - std::make_pair(R"gql(ARGUMENT_DEFINITION)gql"sv, DirectiveLocation::ARGUMENT_DEFINITION), - std::make_pair(R"gql(FRAGMENT_DEFINITION)gql"sv, DirectiveLocation::FRAGMENT_DEFINITION), - std::make_pair(R"gql(VARIABLE_DEFINITION)gql"sv, DirectiveLocation::VARIABLE_DEFINITION), - std::make_pair(R"gql(INPUT_FIELD_DEFINITION)gql"sv, DirectiveLocation::INPUT_FIELD_DEFINITION) - }; -} - class Schema; class Type; class Field; diff --git a/include/graphqlservice/introspection/IntrospectionSchema.ixx b/include/graphqlservice/introspection/IntrospectionSchema.ixx index 45f3f14a..8ce51120 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.ixx +++ b/include/graphqlservice/introspection/IntrospectionSchema.ixx @@ -9,6 +9,8 @@ module; export module GraphQL.Introspection.IntrospectionSchema; +export import GraphQL.Introspection.IntrospectionSharedTypes; + export import GraphQL.Introspection.SchemaObject; export import GraphQL.Introspection.TypeObject; export import GraphQL.Introspection.FieldObject; @@ -18,14 +20,6 @@ export import GraphQL.Introspection.DirectiveObject; export namespace graphql::introspection { -using introspection::TypeKind; -using introspection::getTypeKindNames; -using introspection::getTypeKindValues; - -using introspection::DirectiveLocation; -using introspection::getDirectiveLocationNames; -using introspection::getDirectiveLocationValues; - using introspection::AddSchemaDetails; using introspection::AddTypeDetails; using introspection::AddFieldDetails; diff --git a/include/graphqlservice/introspection/IntrospectionSharedTypes.h b/include/graphqlservice/introspection/IntrospectionSharedTypes.h new file mode 100644 index 00000000..63b71c2c --- /dev/null +++ b/include/graphqlservice/introspection/IntrospectionSharedTypes.h @@ -0,0 +1,151 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef INTROSPECTIONSHAREDTYPES_H +#define INTROSPECTIONSHAREDTYPES_H + +#include "graphqlservice/GraphQLResponse.h" + +#include "graphqlservice/internal/Version.h" + +#include +#include +#include +#include +#include +#include + +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); + +namespace graphql::introspection { + +enum class TypeKind +{ + SCALAR, + OBJECT, + INTERFACE, + UNION, + ENUM, + INPUT_OBJECT, + LIST, + NON_NULL +}; + +[[nodiscard("unnecessary call")]] constexpr auto getTypeKindNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(SCALAR)gql"sv, + R"gql(OBJECT)gql"sv, + R"gql(INTERFACE)gql"sv, + R"gql(UNION)gql"sv, + R"gql(ENUM)gql"sv, + R"gql(INPUT_OBJECT)gql"sv, + R"gql(LIST)gql"sv, + R"gql(NON_NULL)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getTypeKindValues() noexcept +{ + using namespace std::literals; + + return std::array, 8> { + std::make_pair(R"gql(ENUM)gql"sv, TypeKind::ENUM), + std::make_pair(R"gql(LIST)gql"sv, TypeKind::LIST), + std::make_pair(R"gql(UNION)gql"sv, TypeKind::UNION), + std::make_pair(R"gql(OBJECT)gql"sv, TypeKind::OBJECT), + std::make_pair(R"gql(SCALAR)gql"sv, TypeKind::SCALAR), + std::make_pair(R"gql(NON_NULL)gql"sv, TypeKind::NON_NULL), + std::make_pair(R"gql(INTERFACE)gql"sv, TypeKind::INTERFACE), + std::make_pair(R"gql(INPUT_OBJECT)gql"sv, TypeKind::INPUT_OBJECT) + }; +} + +enum class DirectiveLocation +{ + QUERY, + MUTATION, + SUBSCRIPTION, + FIELD, + FRAGMENT_DEFINITION, + FRAGMENT_SPREAD, + INLINE_FRAGMENT, + VARIABLE_DEFINITION, + SCHEMA, + SCALAR, + OBJECT, + FIELD_DEFINITION, + ARGUMENT_DEFINITION, + INTERFACE, + UNION, + ENUM, + ENUM_VALUE, + INPUT_OBJECT, + INPUT_FIELD_DEFINITION +}; + +[[nodiscard("unnecessary call")]] constexpr auto getDirectiveLocationNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(QUERY)gql"sv, + R"gql(MUTATION)gql"sv, + R"gql(SUBSCRIPTION)gql"sv, + R"gql(FIELD)gql"sv, + R"gql(FRAGMENT_DEFINITION)gql"sv, + R"gql(FRAGMENT_SPREAD)gql"sv, + R"gql(INLINE_FRAGMENT)gql"sv, + R"gql(VARIABLE_DEFINITION)gql"sv, + R"gql(SCHEMA)gql"sv, + R"gql(SCALAR)gql"sv, + R"gql(OBJECT)gql"sv, + R"gql(FIELD_DEFINITION)gql"sv, + R"gql(ARGUMENT_DEFINITION)gql"sv, + R"gql(INTERFACE)gql"sv, + R"gql(UNION)gql"sv, + R"gql(ENUM)gql"sv, + R"gql(ENUM_VALUE)gql"sv, + R"gql(INPUT_OBJECT)gql"sv, + R"gql(INPUT_FIELD_DEFINITION)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getDirectiveLocationValues() noexcept +{ + using namespace std::literals; + + return std::array, 19> { + std::make_pair(R"gql(ENUM)gql"sv, DirectiveLocation::ENUM), + std::make_pair(R"gql(FIELD)gql"sv, DirectiveLocation::FIELD), + std::make_pair(R"gql(QUERY)gql"sv, DirectiveLocation::QUERY), + std::make_pair(R"gql(UNION)gql"sv, DirectiveLocation::UNION), + std::make_pair(R"gql(OBJECT)gql"sv, DirectiveLocation::OBJECT), + std::make_pair(R"gql(SCALAR)gql"sv, DirectiveLocation::SCALAR), + std::make_pair(R"gql(SCHEMA)gql"sv, DirectiveLocation::SCHEMA), + std::make_pair(R"gql(MUTATION)gql"sv, DirectiveLocation::MUTATION), + std::make_pair(R"gql(INTERFACE)gql"sv, DirectiveLocation::INTERFACE), + std::make_pair(R"gql(ENUM_VALUE)gql"sv, DirectiveLocation::ENUM_VALUE), + std::make_pair(R"gql(INPUT_OBJECT)gql"sv, DirectiveLocation::INPUT_OBJECT), + std::make_pair(R"gql(SUBSCRIPTION)gql"sv, DirectiveLocation::SUBSCRIPTION), + std::make_pair(R"gql(FRAGMENT_SPREAD)gql"sv, DirectiveLocation::FRAGMENT_SPREAD), + std::make_pair(R"gql(INLINE_FRAGMENT)gql"sv, DirectiveLocation::INLINE_FRAGMENT), + std::make_pair(R"gql(FIELD_DEFINITION)gql"sv, DirectiveLocation::FIELD_DEFINITION), + std::make_pair(R"gql(ARGUMENT_DEFINITION)gql"sv, DirectiveLocation::ARGUMENT_DEFINITION), + std::make_pair(R"gql(FRAGMENT_DEFINITION)gql"sv, DirectiveLocation::FRAGMENT_DEFINITION), + std::make_pair(R"gql(VARIABLE_DEFINITION)gql"sv, DirectiveLocation::VARIABLE_DEFINITION), + std::make_pair(R"gql(INPUT_FIELD_DEFINITION)gql"sv, DirectiveLocation::INPUT_FIELD_DEFINITION) + }; +} + +} // namespace graphql::introspection + +#endif // INTROSPECTIONSHAREDTYPES_H diff --git a/include/graphqlservice/introspection/IntrospectionSharedTypes.ixx b/include/graphqlservice/introspection/IntrospectionSharedTypes.ixx new file mode 100644 index 00000000..60538148 --- /dev/null +++ b/include/graphqlservice/introspection/IntrospectionSharedTypes.ixx @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "IntrospectionSharedTypes.h" + +export module GraphQL.Introspection.IntrospectionSharedTypes; + +export namespace graphql::introspection { + +using introspection::TypeKind; +using introspection::getTypeKindNames; +using introspection::getTypeKindValues; + +using introspection::DirectiveLocation; +using introspection::getDirectiveLocationNames; +using introspection::getDirectiveLocationValues; + +} // namespace graphql::introspection diff --git a/samples/learn/schema/StarWarsSchema.h b/samples/learn/schema/StarWarsSchema.h index 11950217..5182070f 100644 --- a/samples/learn/schema/StarWarsSchema.h +++ b/samples/learn/schema/StarWarsSchema.h @@ -14,6 +14,8 @@ #include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" +#include "StarWarsSharedTypes.h" + #include #include #include @@ -25,53 +27,6 @@ static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: namespace graphql { namespace learn { - -enum class [[nodiscard("unnecessary conversion")]] Episode -{ - NEW_HOPE, - EMPIRE, - JEDI -}; - -[[nodiscard("unnecessary call")]] constexpr auto getEpisodeNames() noexcept -{ - using namespace std::literals; - - return std::array { - R"gql(NEW_HOPE)gql"sv, - R"gql(EMPIRE)gql"sv, - R"gql(JEDI)gql"sv - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto getEpisodeValues() noexcept -{ - using namespace std::literals; - - return std::array, 3> { - std::make_pair(R"gql(JEDI)gql"sv, Episode::JEDI), - std::make_pair(R"gql(EMPIRE)gql"sv, Episode::EMPIRE), - std::make_pair(R"gql(NEW_HOPE)gql"sv, Episode::NEW_HOPE) - }; -} - -struct [[nodiscard("unnecessary construction")]] ReviewInput -{ - explicit ReviewInput() noexcept; - explicit ReviewInput( - int starsArg, - std::optional commentaryArg) noexcept; - ReviewInput(const ReviewInput& other); - ReviewInput(ReviewInput&& other) noexcept; - ~ReviewInput(); - - ReviewInput& operator=(const ReviewInput& other); - ReviewInput& operator=(ReviewInput&& other) noexcept; - - int stars; - std::optional commentary; -}; - namespace object { class Character; diff --git a/samples/learn/schema/StarWarsSchema.ixx b/samples/learn/schema/StarWarsSchema.ixx index 1a339c7c..838f2815 100644 --- a/samples/learn/schema/StarWarsSchema.ixx +++ b/samples/learn/schema/StarWarsSchema.ixx @@ -9,6 +9,8 @@ module; export module GraphQL.StarWars.StarWarsSchema; +export import GraphQL.StarWars.StarWarsSharedTypes; + export import GraphQL.StarWars.CharacterObject; export import GraphQL.StarWars.HumanObject; export import GraphQL.StarWars.DroidObject; @@ -19,12 +21,6 @@ export import GraphQL.StarWars.SubscriptionObject; export namespace graphql::learn { -using learn::Episode; -using learn::getEpisodeNames; -using learn::getEpisodeValues; - -using learn::ReviewInput; - using learn::Operations; using learn::AddCharacterDetails; diff --git a/samples/learn/schema/StarWarsSharedTypes.h b/samples/learn/schema/StarWarsSharedTypes.h new file mode 100644 index 00000000..007c2b19 --- /dev/null +++ b/samples/learn/schema/StarWarsSharedTypes.h @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef STARWARSSHAREDTYPES_H +#define STARWARSSHAREDTYPES_H + +#include "graphqlservice/GraphQLResponse.h" + +#include "graphqlservice/internal/Version.h" + +#include +#include +#include +#include +#include +#include + +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); + +namespace graphql::learn { + +enum class [[nodiscard("unnecessary conversion")]] Episode +{ + NEW_HOPE, + EMPIRE, + JEDI +}; + +[[nodiscard("unnecessary call")]] constexpr auto getEpisodeNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(NEW_HOPE)gql"sv, + R"gql(EMPIRE)gql"sv, + R"gql(JEDI)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getEpisodeValues() noexcept +{ + using namespace std::literals; + + return std::array, 3> { + std::make_pair(R"gql(JEDI)gql"sv, Episode::JEDI), + std::make_pair(R"gql(EMPIRE)gql"sv, Episode::EMPIRE), + std::make_pair(R"gql(NEW_HOPE)gql"sv, Episode::NEW_HOPE) + }; +} + +struct [[nodiscard("unnecessary construction")]] ReviewInput +{ + explicit ReviewInput() noexcept; + explicit ReviewInput( + int starsArg, + std::optional commentaryArg) noexcept; + ReviewInput(const ReviewInput& other); + ReviewInput(ReviewInput&& other) noexcept; + ~ReviewInput(); + + ReviewInput& operator=(const ReviewInput& other); + ReviewInput& operator=(ReviewInput&& other) noexcept; + + int stars; + std::optional commentary; +}; + +} // namespace graphql::learn + +#endif // STARWARSSHAREDTYPES_H diff --git a/samples/learn/schema/StarWarsSharedTypes.ixx b/samples/learn/schema/StarWarsSharedTypes.ixx new file mode 100644 index 00000000..5e6a2fa2 --- /dev/null +++ b/samples/learn/schema/StarWarsSharedTypes.ixx @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "StarWarsSharedTypes.h" + +export module GraphQL.StarWars.StarWarsSharedTypes; + +export namespace graphql::learn { + +using learn::Episode; +using learn::getEpisodeNames; +using learn::getEpisodeValues; + +using learn::ReviewInput; + +} // namespace graphql::learn diff --git a/samples/proxy/schema/ProxySchema.h b/samples/proxy/schema/ProxySchema.h index 849cfb60..1fd0922f 100644 --- a/samples/proxy/schema/ProxySchema.h +++ b/samples/proxy/schema/ProxySchema.h @@ -14,6 +14,8 @@ #include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" +#include "ProxySharedTypes.h" + #include #include #include @@ -25,57 +27,6 @@ static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: namespace graphql { namespace proxy { - -enum class [[nodiscard("unnecessary conversion")]] OperationType -{ - QUERY, - MUTATION, - SUBSCRIPTION -}; - -[[nodiscard("unnecessary call")]] constexpr auto getOperationTypeNames() noexcept -{ - using namespace std::literals; - - return std::array { - R"gql(QUERY)gql"sv, - R"gql(MUTATION)gql"sv, - R"gql(SUBSCRIPTION)gql"sv - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto getOperationTypeValues() noexcept -{ - using namespace std::literals; - - return std::array, 3> { - std::make_pair(R"gql(QUERY)gql"sv, OperationType::QUERY), - std::make_pair(R"gql(MUTATION)gql"sv, OperationType::MUTATION), - std::make_pair(R"gql(SUBSCRIPTION)gql"sv, OperationType::SUBSCRIPTION) - }; -} - -struct [[nodiscard("unnecessary construction")]] QueryInput -{ - explicit QueryInput() noexcept; - explicit QueryInput( - OperationType typeArg, - std::string queryArg, - std::optional operationNameArg, - std::optional variablesArg) noexcept; - QueryInput(const QueryInput& other); - QueryInput(QueryInput&& other) noexcept; - ~QueryInput(); - - QueryInput& operator=(const QueryInput& other); - QueryInput& operator=(QueryInput&& other) noexcept; - - OperationType type; - std::string query; - std::optional operationName; - std::optional variables; -}; - namespace object { class Query; diff --git a/samples/proxy/schema/ProxySchema.ixx b/samples/proxy/schema/ProxySchema.ixx index 0b646c10..6e5893e3 100644 --- a/samples/proxy/schema/ProxySchema.ixx +++ b/samples/proxy/schema/ProxySchema.ixx @@ -9,17 +9,13 @@ module; export module GraphQL.Proxy.ProxySchema; +export import GraphQL.Proxy.ProxySharedTypes; + export import GraphQL.Proxy.QueryObject; export import GraphQL.Proxy.QueryResultsObject; export namespace graphql::proxy { -using proxy::OperationType; -using proxy::getOperationTypeNames; -using proxy::getOperationTypeValues; - -using proxy::QueryInput; - using proxy::Operations; using proxy::AddQueryDetails; diff --git a/samples/proxy/schema/ProxySharedTypes.h b/samples/proxy/schema/ProxySharedTypes.h new file mode 100644 index 00000000..48f821a2 --- /dev/null +++ b/samples/proxy/schema/ProxySharedTypes.h @@ -0,0 +1,80 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef PROXYSHAREDTYPES_H +#define PROXYSHAREDTYPES_H + +#include "graphqlservice/GraphQLResponse.h" + +#include "graphqlservice/internal/Version.h" + +#include +#include +#include +#include +#include +#include + +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); + +namespace graphql::proxy { + +enum class [[nodiscard("unnecessary conversion")]] OperationType +{ + QUERY, + MUTATION, + SUBSCRIPTION +}; + +[[nodiscard("unnecessary call")]] constexpr auto getOperationTypeNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(QUERY)gql"sv, + R"gql(MUTATION)gql"sv, + R"gql(SUBSCRIPTION)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getOperationTypeValues() noexcept +{ + using namespace std::literals; + + return std::array, 3> { + std::make_pair(R"gql(QUERY)gql"sv, OperationType::QUERY), + std::make_pair(R"gql(MUTATION)gql"sv, OperationType::MUTATION), + std::make_pair(R"gql(SUBSCRIPTION)gql"sv, OperationType::SUBSCRIPTION) + }; +} + +struct [[nodiscard("unnecessary construction")]] QueryInput +{ + explicit QueryInput() noexcept; + explicit QueryInput( + OperationType typeArg, + std::string queryArg, + std::optional operationNameArg, + std::optional variablesArg) noexcept; + QueryInput(const QueryInput& other); + QueryInput(QueryInput&& other) noexcept; + ~QueryInput(); + + QueryInput& operator=(const QueryInput& other); + QueryInput& operator=(QueryInput&& other) noexcept; + + OperationType type; + std::string query; + std::optional operationName; + std::optional variables; +}; + +} // namespace graphql::proxy + +#endif // PROXYSHAREDTYPES_H diff --git a/samples/proxy/schema/ProxySharedTypes.ixx b/samples/proxy/schema/ProxySharedTypes.ixx new file mode 100644 index 00000000..75dd847d --- /dev/null +++ b/samples/proxy/schema/ProxySharedTypes.ixx @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ProxySharedTypes.h" + +export module GraphQL.Proxy.ProxySharedTypes; + +export namespace graphql::proxy { + +using proxy::OperationType; +using proxy::getOperationTypeNames; +using proxy::getOperationTypeValues; + +using proxy::QueryInput; + +} // namespace graphql::proxy diff --git a/samples/today/nointrospection/TodaySchema.h b/samples/today/nointrospection/TodaySchema.h index 3798db11..594c9264 100644 --- a/samples/today/nointrospection/TodaySchema.h +++ b/samples/today/nointrospection/TodaySchema.h @@ -14,6 +14,8 @@ #include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" +#include "TodaySharedTypes.h" + #include #include #include @@ -25,214 +27,6 @@ static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: namespace graphql { namespace today { - -enum class [[nodiscard("unnecessary conversion")]] TaskState -{ - Unassigned, - New, - Started, - Complete -}; - -[[nodiscard("unnecessary call")]] constexpr auto getTaskStateNames() noexcept -{ - using namespace std::literals; - - return std::array { - R"gql(Unassigned)gql"sv, - R"gql(New)gql"sv, - R"gql(Started)gql"sv, - R"gql(Complete)gql"sv - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto getTaskStateValues() noexcept -{ - using namespace std::literals; - - return std::array, 4> { - std::make_pair(R"gql(New)gql"sv, TaskState::New), - std::make_pair(R"gql(Started)gql"sv, TaskState::Started), - std::make_pair(R"gql(Complete)gql"sv, TaskState::Complete), - std::make_pair(R"gql(Unassigned)gql"sv, TaskState::Unassigned) - }; -} - -struct [[nodiscard("unnecessary construction")]] CompleteTaskInput -{ - explicit CompleteTaskInput() noexcept; - explicit CompleteTaskInput( - response::IdType idArg, - std::optional testTaskStateArg, - std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept; - CompleteTaskInput(const CompleteTaskInput& other); - CompleteTaskInput(CompleteTaskInput&& other) noexcept; - ~CompleteTaskInput(); - - CompleteTaskInput& operator=(const CompleteTaskInput& other); - CompleteTaskInput& operator=(CompleteTaskInput&& other) noexcept; - - response::IdType id; - std::optional testTaskState; - std::optional isComplete; - std::optional clientMutationId; -}; - -struct SecondNestedInput; - -struct [[nodiscard("unnecessary construction")]] ThirdNestedInput -{ - explicit ThirdNestedInput() noexcept; - explicit ThirdNestedInput( - response::IdType idArg, - std::unique_ptr secondArg) noexcept; - ThirdNestedInput(const ThirdNestedInput& other); - ThirdNestedInput(ThirdNestedInput&& other) noexcept; - ~ThirdNestedInput(); - - ThirdNestedInput& operator=(const ThirdNestedInput& other); - ThirdNestedInput& operator=(ThirdNestedInput&& other) noexcept; - - response::IdType id; - std::unique_ptr second; -}; - -struct [[nodiscard("unnecessary construction")]] FourthNestedInput -{ - explicit FourthNestedInput() noexcept; - explicit FourthNestedInput( - response::IdType idArg) noexcept; - FourthNestedInput(const FourthNestedInput& other); - FourthNestedInput(FourthNestedInput&& other) noexcept; - ~FourthNestedInput(); - - FourthNestedInput& operator=(const FourthNestedInput& other); - FourthNestedInput& operator=(FourthNestedInput&& other) noexcept; - - response::IdType id; -}; - -struct [[nodiscard("unnecessary construction")]] IncludeNullableSelfInput -{ - explicit IncludeNullableSelfInput() noexcept; - explicit IncludeNullableSelfInput( - std::unique_ptr selfArg) noexcept; - IncludeNullableSelfInput(const IncludeNullableSelfInput& other); - IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept; - ~IncludeNullableSelfInput(); - - IncludeNullableSelfInput& operator=(const IncludeNullableSelfInput& other); - IncludeNullableSelfInput& operator=(IncludeNullableSelfInput&& other) noexcept; - - std::unique_ptr self; -}; - -struct [[nodiscard("unnecessary construction")]] IncludeNonNullableListSelfInput -{ - explicit IncludeNonNullableListSelfInput() noexcept; - explicit IncludeNonNullableListSelfInput( - std::vector selvesArg) noexcept; - IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other); - IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept; - ~IncludeNonNullableListSelfInput(); - - IncludeNonNullableListSelfInput& operator=(const IncludeNonNullableListSelfInput& other); - IncludeNonNullableListSelfInput& operator=(IncludeNonNullableListSelfInput&& other) noexcept; - - std::vector selves; -}; - -struct [[nodiscard("unnecessary construction")]] StringOperationFilterInput -{ - explicit StringOperationFilterInput() noexcept; - explicit StringOperationFilterInput( - std::optional> and_Arg, - std::optional> or_Arg, - std::optional equalArg, - std::optional notEqualArg, - std::optional containsArg, - std::optional notContainsArg, - std::optional> inArg, - std::optional> notInArg, - std::optional startsWithArg, - std::optional notStartsWithArg, - std::optional endsWithArg, - std::optional notEndsWithArg) noexcept; - StringOperationFilterInput(const StringOperationFilterInput& other); - StringOperationFilterInput(StringOperationFilterInput&& other) noexcept; - ~StringOperationFilterInput(); - - StringOperationFilterInput& operator=(const StringOperationFilterInput& other); - StringOperationFilterInput& operator=(StringOperationFilterInput&& other) noexcept; - - std::optional> and_; - std::optional> or_; - std::optional equal; - std::optional notEqual; - std::optional contains; - std::optional notContains; - std::optional> in; - std::optional> notIn; - std::optional startsWith; - std::optional notStartsWith; - std::optional endsWith; - std::optional notEndsWith; -}; - -struct [[nodiscard("unnecessary construction")]] SecondNestedInput -{ - explicit SecondNestedInput() noexcept; - explicit SecondNestedInput( - response::IdType idArg, - ThirdNestedInput thirdArg) noexcept; - SecondNestedInput(const SecondNestedInput& other); - SecondNestedInput(SecondNestedInput&& other) noexcept; - ~SecondNestedInput(); - - SecondNestedInput& operator=(const SecondNestedInput& other); - SecondNestedInput& operator=(SecondNestedInput&& other) noexcept; - - response::IdType id; - ThirdNestedInput third; -}; - -struct [[nodiscard("unnecessary construction")]] ForwardDeclaredInput -{ - explicit ForwardDeclaredInput() noexcept; - explicit ForwardDeclaredInput( - std::unique_ptr nullableSelfArg, - IncludeNonNullableListSelfInput listSelvesArg) noexcept; - ForwardDeclaredInput(const ForwardDeclaredInput& other); - ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept; - ~ForwardDeclaredInput(); - - ForwardDeclaredInput& operator=(const ForwardDeclaredInput& other); - ForwardDeclaredInput& operator=(ForwardDeclaredInput&& other) noexcept; - - std::unique_ptr nullableSelf; - IncludeNonNullableListSelfInput listSelves; -}; - -struct [[nodiscard("unnecessary construction")]] FirstNestedInput -{ - explicit FirstNestedInput() noexcept; - explicit FirstNestedInput( - response::IdType idArg, - SecondNestedInput secondArg, - ThirdNestedInput thirdArg) noexcept; - FirstNestedInput(const FirstNestedInput& other); - FirstNestedInput(FirstNestedInput&& other) noexcept; - ~FirstNestedInput(); - - FirstNestedInput& operator=(const FirstNestedInput& other); - FirstNestedInput& operator=(FirstNestedInput&& other) noexcept; - - response::IdType id; - SecondNestedInput second; - ThirdNestedInput third; -}; - namespace object { class Node; diff --git a/samples/today/nointrospection/TodaySchema.ixx b/samples/today/nointrospection/TodaySchema.ixx index 7bfef47c..56aad8e6 100644 --- a/samples/today/nointrospection/TodaySchema.ixx +++ b/samples/today/nointrospection/TodaySchema.ixx @@ -9,6 +9,8 @@ module; export module GraphQL.Today.TodaySchema; +export import GraphQL.Today.TodaySharedTypes; + export import GraphQL.Today.NodeObject; export import GraphQL.Today.UnionTypeObject; export import GraphQL.Today.QueryObject; @@ -30,20 +32,6 @@ export import GraphQL.Today.ExpensiveObject; export namespace graphql::today { -using today::TaskState; -using today::getTaskStateNames; -using today::getTaskStateValues; - -using today::CompleteTaskInput; -using today::ThirdNestedInput; -using today::FourthNestedInput; -using today::IncludeNullableSelfInput; -using today::IncludeNonNullableListSelfInput; -using today::StringOperationFilterInput; -using today::SecondNestedInput; -using today::ForwardDeclaredInput; -using today::FirstNestedInput; - using today::Operations; using today::AddNodeDetails; diff --git a/samples/today/nointrospection/TodaySharedTypes.h b/samples/today/nointrospection/TodaySharedTypes.h new file mode 100644 index 00000000..39774106 --- /dev/null +++ b/samples/today/nointrospection/TodaySharedTypes.h @@ -0,0 +1,237 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef TODAYSHAREDTYPES_H +#define TODAYSHAREDTYPES_H + +#include "graphqlservice/GraphQLResponse.h" + +#include "graphqlservice/internal/Version.h" + +#include +#include +#include +#include +#include +#include + +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); + +namespace graphql::today { + +enum class [[nodiscard("unnecessary conversion")]] TaskState +{ + Unassigned, + New, + Started, + Complete +}; + +[[nodiscard("unnecessary call")]] constexpr auto getTaskStateNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(Unassigned)gql"sv, + R"gql(New)gql"sv, + R"gql(Started)gql"sv, + R"gql(Complete)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getTaskStateValues() noexcept +{ + using namespace std::literals; + + return std::array, 4> { + std::make_pair(R"gql(New)gql"sv, TaskState::New), + std::make_pair(R"gql(Started)gql"sv, TaskState::Started), + std::make_pair(R"gql(Complete)gql"sv, TaskState::Complete), + std::make_pair(R"gql(Unassigned)gql"sv, TaskState::Unassigned) + }; +} + +struct [[nodiscard("unnecessary construction")]] CompleteTaskInput +{ + explicit CompleteTaskInput() noexcept; + explicit CompleteTaskInput( + response::IdType idArg, + std::optional testTaskStateArg, + std::optional isCompleteArg, + std::optional clientMutationIdArg) noexcept; + CompleteTaskInput(const CompleteTaskInput& other); + CompleteTaskInput(CompleteTaskInput&& other) noexcept; + ~CompleteTaskInput(); + + CompleteTaskInput& operator=(const CompleteTaskInput& other); + CompleteTaskInput& operator=(CompleteTaskInput&& other) noexcept; + + response::IdType id; + std::optional testTaskState; + std::optional isComplete; + std::optional clientMutationId; +}; + +struct SecondNestedInput; + +struct [[nodiscard("unnecessary construction")]] ThirdNestedInput +{ + explicit ThirdNestedInput() noexcept; + explicit ThirdNestedInput( + response::IdType idArg, + std::unique_ptr secondArg) noexcept; + ThirdNestedInput(const ThirdNestedInput& other); + ThirdNestedInput(ThirdNestedInput&& other) noexcept; + ~ThirdNestedInput(); + + ThirdNestedInput& operator=(const ThirdNestedInput& other); + ThirdNestedInput& operator=(ThirdNestedInput&& other) noexcept; + + response::IdType id; + std::unique_ptr second; +}; + +struct [[nodiscard("unnecessary construction")]] FourthNestedInput +{ + explicit FourthNestedInput() noexcept; + explicit FourthNestedInput( + response::IdType idArg) noexcept; + FourthNestedInput(const FourthNestedInput& other); + FourthNestedInput(FourthNestedInput&& other) noexcept; + ~FourthNestedInput(); + + FourthNestedInput& operator=(const FourthNestedInput& other); + FourthNestedInput& operator=(FourthNestedInput&& other) noexcept; + + response::IdType id; +}; + +struct [[nodiscard("unnecessary construction")]] IncludeNullableSelfInput +{ + explicit IncludeNullableSelfInput() noexcept; + explicit IncludeNullableSelfInput( + std::unique_ptr selfArg) noexcept; + IncludeNullableSelfInput(const IncludeNullableSelfInput& other); + IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept; + ~IncludeNullableSelfInput(); + + IncludeNullableSelfInput& operator=(const IncludeNullableSelfInput& other); + IncludeNullableSelfInput& operator=(IncludeNullableSelfInput&& other) noexcept; + + std::unique_ptr self; +}; + +struct [[nodiscard("unnecessary construction")]] IncludeNonNullableListSelfInput +{ + explicit IncludeNonNullableListSelfInput() noexcept; + explicit IncludeNonNullableListSelfInput( + std::vector selvesArg) noexcept; + IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other); + IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept; + ~IncludeNonNullableListSelfInput(); + + IncludeNonNullableListSelfInput& operator=(const IncludeNonNullableListSelfInput& other); + IncludeNonNullableListSelfInput& operator=(IncludeNonNullableListSelfInput&& other) noexcept; + + std::vector selves; +}; + +struct [[nodiscard("unnecessary construction")]] StringOperationFilterInput +{ + explicit StringOperationFilterInput() noexcept; + explicit StringOperationFilterInput( + std::optional> and_Arg, + std::optional> or_Arg, + std::optional equalArg, + std::optional notEqualArg, + std::optional containsArg, + std::optional notContainsArg, + std::optional> inArg, + std::optional> notInArg, + std::optional startsWithArg, + std::optional notStartsWithArg, + std::optional endsWithArg, + std::optional notEndsWithArg) noexcept; + StringOperationFilterInput(const StringOperationFilterInput& other); + StringOperationFilterInput(StringOperationFilterInput&& other) noexcept; + ~StringOperationFilterInput(); + + StringOperationFilterInput& operator=(const StringOperationFilterInput& other); + StringOperationFilterInput& operator=(StringOperationFilterInput&& other) noexcept; + + std::optional> and_; + std::optional> or_; + std::optional equal; + std::optional notEqual; + std::optional contains; + std::optional notContains; + std::optional> in; + std::optional> notIn; + std::optional startsWith; + std::optional notStartsWith; + std::optional endsWith; + std::optional notEndsWith; +}; + +struct [[nodiscard("unnecessary construction")]] SecondNestedInput +{ + explicit SecondNestedInput() noexcept; + explicit SecondNestedInput( + response::IdType idArg, + ThirdNestedInput thirdArg) noexcept; + SecondNestedInput(const SecondNestedInput& other); + SecondNestedInput(SecondNestedInput&& other) noexcept; + ~SecondNestedInput(); + + SecondNestedInput& operator=(const SecondNestedInput& other); + SecondNestedInput& operator=(SecondNestedInput&& other) noexcept; + + response::IdType id; + ThirdNestedInput third; +}; + +struct [[nodiscard("unnecessary construction")]] ForwardDeclaredInput +{ + explicit ForwardDeclaredInput() noexcept; + explicit ForwardDeclaredInput( + std::unique_ptr nullableSelfArg, + IncludeNonNullableListSelfInput listSelvesArg) noexcept; + ForwardDeclaredInput(const ForwardDeclaredInput& other); + ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept; + ~ForwardDeclaredInput(); + + ForwardDeclaredInput& operator=(const ForwardDeclaredInput& other); + ForwardDeclaredInput& operator=(ForwardDeclaredInput&& other) noexcept; + + std::unique_ptr nullableSelf; + IncludeNonNullableListSelfInput listSelves; +}; + +struct [[nodiscard("unnecessary construction")]] FirstNestedInput +{ + explicit FirstNestedInput() noexcept; + explicit FirstNestedInput( + response::IdType idArg, + SecondNestedInput secondArg, + ThirdNestedInput thirdArg) noexcept; + FirstNestedInput(const FirstNestedInput& other); + FirstNestedInput(FirstNestedInput&& other) noexcept; + ~FirstNestedInput(); + + FirstNestedInput& operator=(const FirstNestedInput& other); + FirstNestedInput& operator=(FirstNestedInput&& other) noexcept; + + response::IdType id; + SecondNestedInput second; + ThirdNestedInput third; +}; + +} // namespace graphql::today + +#endif // TODAYSHAREDTYPES_H diff --git a/samples/today/nointrospection/TodaySharedTypes.ixx b/samples/today/nointrospection/TodaySharedTypes.ixx new file mode 100644 index 00000000..ee76a95a --- /dev/null +++ b/samples/today/nointrospection/TodaySharedTypes.ixx @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TodaySharedTypes.h" + +export module GraphQL.Today.TodaySharedTypes; + +export namespace graphql::today { + +using today::TaskState; +using today::getTaskStateNames; +using today::getTaskStateValues; + +using today::CompleteTaskInput; +using today::ThirdNestedInput; +using today::FourthNestedInput; +using today::IncludeNullableSelfInput; +using today::IncludeNonNullableListSelfInput; +using today::StringOperationFilterInput; +using today::SecondNestedInput; +using today::ForwardDeclaredInput; +using today::FirstNestedInput; + +} // namespace graphql::today diff --git a/samples/today/schema/TodaySchema.h b/samples/today/schema/TodaySchema.h index 3798db11..594c9264 100644 --- a/samples/today/schema/TodaySchema.h +++ b/samples/today/schema/TodaySchema.h @@ -14,6 +14,8 @@ #include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" +#include "TodaySharedTypes.h" + #include #include #include @@ -25,214 +27,6 @@ static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: namespace graphql { namespace today { - -enum class [[nodiscard("unnecessary conversion")]] TaskState -{ - Unassigned, - New, - Started, - Complete -}; - -[[nodiscard("unnecessary call")]] constexpr auto getTaskStateNames() noexcept -{ - using namespace std::literals; - - return std::array { - R"gql(Unassigned)gql"sv, - R"gql(New)gql"sv, - R"gql(Started)gql"sv, - R"gql(Complete)gql"sv - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto getTaskStateValues() noexcept -{ - using namespace std::literals; - - return std::array, 4> { - std::make_pair(R"gql(New)gql"sv, TaskState::New), - std::make_pair(R"gql(Started)gql"sv, TaskState::Started), - std::make_pair(R"gql(Complete)gql"sv, TaskState::Complete), - std::make_pair(R"gql(Unassigned)gql"sv, TaskState::Unassigned) - }; -} - -struct [[nodiscard("unnecessary construction")]] CompleteTaskInput -{ - explicit CompleteTaskInput() noexcept; - explicit CompleteTaskInput( - response::IdType idArg, - std::optional testTaskStateArg, - std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept; - CompleteTaskInput(const CompleteTaskInput& other); - CompleteTaskInput(CompleteTaskInput&& other) noexcept; - ~CompleteTaskInput(); - - CompleteTaskInput& operator=(const CompleteTaskInput& other); - CompleteTaskInput& operator=(CompleteTaskInput&& other) noexcept; - - response::IdType id; - std::optional testTaskState; - std::optional isComplete; - std::optional clientMutationId; -}; - -struct SecondNestedInput; - -struct [[nodiscard("unnecessary construction")]] ThirdNestedInput -{ - explicit ThirdNestedInput() noexcept; - explicit ThirdNestedInput( - response::IdType idArg, - std::unique_ptr secondArg) noexcept; - ThirdNestedInput(const ThirdNestedInput& other); - ThirdNestedInput(ThirdNestedInput&& other) noexcept; - ~ThirdNestedInput(); - - ThirdNestedInput& operator=(const ThirdNestedInput& other); - ThirdNestedInput& operator=(ThirdNestedInput&& other) noexcept; - - response::IdType id; - std::unique_ptr second; -}; - -struct [[nodiscard("unnecessary construction")]] FourthNestedInput -{ - explicit FourthNestedInput() noexcept; - explicit FourthNestedInput( - response::IdType idArg) noexcept; - FourthNestedInput(const FourthNestedInput& other); - FourthNestedInput(FourthNestedInput&& other) noexcept; - ~FourthNestedInput(); - - FourthNestedInput& operator=(const FourthNestedInput& other); - FourthNestedInput& operator=(FourthNestedInput&& other) noexcept; - - response::IdType id; -}; - -struct [[nodiscard("unnecessary construction")]] IncludeNullableSelfInput -{ - explicit IncludeNullableSelfInput() noexcept; - explicit IncludeNullableSelfInput( - std::unique_ptr selfArg) noexcept; - IncludeNullableSelfInput(const IncludeNullableSelfInput& other); - IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept; - ~IncludeNullableSelfInput(); - - IncludeNullableSelfInput& operator=(const IncludeNullableSelfInput& other); - IncludeNullableSelfInput& operator=(IncludeNullableSelfInput&& other) noexcept; - - std::unique_ptr self; -}; - -struct [[nodiscard("unnecessary construction")]] IncludeNonNullableListSelfInput -{ - explicit IncludeNonNullableListSelfInput() noexcept; - explicit IncludeNonNullableListSelfInput( - std::vector selvesArg) noexcept; - IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other); - IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept; - ~IncludeNonNullableListSelfInput(); - - IncludeNonNullableListSelfInput& operator=(const IncludeNonNullableListSelfInput& other); - IncludeNonNullableListSelfInput& operator=(IncludeNonNullableListSelfInput&& other) noexcept; - - std::vector selves; -}; - -struct [[nodiscard("unnecessary construction")]] StringOperationFilterInput -{ - explicit StringOperationFilterInput() noexcept; - explicit StringOperationFilterInput( - std::optional> and_Arg, - std::optional> or_Arg, - std::optional equalArg, - std::optional notEqualArg, - std::optional containsArg, - std::optional notContainsArg, - std::optional> inArg, - std::optional> notInArg, - std::optional startsWithArg, - std::optional notStartsWithArg, - std::optional endsWithArg, - std::optional notEndsWithArg) noexcept; - StringOperationFilterInput(const StringOperationFilterInput& other); - StringOperationFilterInput(StringOperationFilterInput&& other) noexcept; - ~StringOperationFilterInput(); - - StringOperationFilterInput& operator=(const StringOperationFilterInput& other); - StringOperationFilterInput& operator=(StringOperationFilterInput&& other) noexcept; - - std::optional> and_; - std::optional> or_; - std::optional equal; - std::optional notEqual; - std::optional contains; - std::optional notContains; - std::optional> in; - std::optional> notIn; - std::optional startsWith; - std::optional notStartsWith; - std::optional endsWith; - std::optional notEndsWith; -}; - -struct [[nodiscard("unnecessary construction")]] SecondNestedInput -{ - explicit SecondNestedInput() noexcept; - explicit SecondNestedInput( - response::IdType idArg, - ThirdNestedInput thirdArg) noexcept; - SecondNestedInput(const SecondNestedInput& other); - SecondNestedInput(SecondNestedInput&& other) noexcept; - ~SecondNestedInput(); - - SecondNestedInput& operator=(const SecondNestedInput& other); - SecondNestedInput& operator=(SecondNestedInput&& other) noexcept; - - response::IdType id; - ThirdNestedInput third; -}; - -struct [[nodiscard("unnecessary construction")]] ForwardDeclaredInput -{ - explicit ForwardDeclaredInput() noexcept; - explicit ForwardDeclaredInput( - std::unique_ptr nullableSelfArg, - IncludeNonNullableListSelfInput listSelvesArg) noexcept; - ForwardDeclaredInput(const ForwardDeclaredInput& other); - ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept; - ~ForwardDeclaredInput(); - - ForwardDeclaredInput& operator=(const ForwardDeclaredInput& other); - ForwardDeclaredInput& operator=(ForwardDeclaredInput&& other) noexcept; - - std::unique_ptr nullableSelf; - IncludeNonNullableListSelfInput listSelves; -}; - -struct [[nodiscard("unnecessary construction")]] FirstNestedInput -{ - explicit FirstNestedInput() noexcept; - explicit FirstNestedInput( - response::IdType idArg, - SecondNestedInput secondArg, - ThirdNestedInput thirdArg) noexcept; - FirstNestedInput(const FirstNestedInput& other); - FirstNestedInput(FirstNestedInput&& other) noexcept; - ~FirstNestedInput(); - - FirstNestedInput& operator=(const FirstNestedInput& other); - FirstNestedInput& operator=(FirstNestedInput&& other) noexcept; - - response::IdType id; - SecondNestedInput second; - ThirdNestedInput third; -}; - namespace object { class Node; diff --git a/samples/today/schema/TodaySchema.ixx b/samples/today/schema/TodaySchema.ixx index 7bfef47c..56aad8e6 100644 --- a/samples/today/schema/TodaySchema.ixx +++ b/samples/today/schema/TodaySchema.ixx @@ -9,6 +9,8 @@ module; export module GraphQL.Today.TodaySchema; +export import GraphQL.Today.TodaySharedTypes; + export import GraphQL.Today.NodeObject; export import GraphQL.Today.UnionTypeObject; export import GraphQL.Today.QueryObject; @@ -30,20 +32,6 @@ export import GraphQL.Today.ExpensiveObject; export namespace graphql::today { -using today::TaskState; -using today::getTaskStateNames; -using today::getTaskStateValues; - -using today::CompleteTaskInput; -using today::ThirdNestedInput; -using today::FourthNestedInput; -using today::IncludeNullableSelfInput; -using today::IncludeNonNullableListSelfInput; -using today::StringOperationFilterInput; -using today::SecondNestedInput; -using today::ForwardDeclaredInput; -using today::FirstNestedInput; - using today::Operations; using today::AddNodeDetails; diff --git a/samples/today/schema/TodaySharedTypes.h b/samples/today/schema/TodaySharedTypes.h new file mode 100644 index 00000000..39774106 --- /dev/null +++ b/samples/today/schema/TodaySharedTypes.h @@ -0,0 +1,237 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef TODAYSHAREDTYPES_H +#define TODAYSHAREDTYPES_H + +#include "graphqlservice/GraphQLResponse.h" + +#include "graphqlservice/internal/Version.h" + +#include +#include +#include +#include +#include +#include + +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); + +namespace graphql::today { + +enum class [[nodiscard("unnecessary conversion")]] TaskState +{ + Unassigned, + New, + Started, + Complete +}; + +[[nodiscard("unnecessary call")]] constexpr auto getTaskStateNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(Unassigned)gql"sv, + R"gql(New)gql"sv, + R"gql(Started)gql"sv, + R"gql(Complete)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getTaskStateValues() noexcept +{ + using namespace std::literals; + + return std::array, 4> { + std::make_pair(R"gql(New)gql"sv, TaskState::New), + std::make_pair(R"gql(Started)gql"sv, TaskState::Started), + std::make_pair(R"gql(Complete)gql"sv, TaskState::Complete), + std::make_pair(R"gql(Unassigned)gql"sv, TaskState::Unassigned) + }; +} + +struct [[nodiscard("unnecessary construction")]] CompleteTaskInput +{ + explicit CompleteTaskInput() noexcept; + explicit CompleteTaskInput( + response::IdType idArg, + std::optional testTaskStateArg, + std::optional isCompleteArg, + std::optional clientMutationIdArg) noexcept; + CompleteTaskInput(const CompleteTaskInput& other); + CompleteTaskInput(CompleteTaskInput&& other) noexcept; + ~CompleteTaskInput(); + + CompleteTaskInput& operator=(const CompleteTaskInput& other); + CompleteTaskInput& operator=(CompleteTaskInput&& other) noexcept; + + response::IdType id; + std::optional testTaskState; + std::optional isComplete; + std::optional clientMutationId; +}; + +struct SecondNestedInput; + +struct [[nodiscard("unnecessary construction")]] ThirdNestedInput +{ + explicit ThirdNestedInput() noexcept; + explicit ThirdNestedInput( + response::IdType idArg, + std::unique_ptr secondArg) noexcept; + ThirdNestedInput(const ThirdNestedInput& other); + ThirdNestedInput(ThirdNestedInput&& other) noexcept; + ~ThirdNestedInput(); + + ThirdNestedInput& operator=(const ThirdNestedInput& other); + ThirdNestedInput& operator=(ThirdNestedInput&& other) noexcept; + + response::IdType id; + std::unique_ptr second; +}; + +struct [[nodiscard("unnecessary construction")]] FourthNestedInput +{ + explicit FourthNestedInput() noexcept; + explicit FourthNestedInput( + response::IdType idArg) noexcept; + FourthNestedInput(const FourthNestedInput& other); + FourthNestedInput(FourthNestedInput&& other) noexcept; + ~FourthNestedInput(); + + FourthNestedInput& operator=(const FourthNestedInput& other); + FourthNestedInput& operator=(FourthNestedInput&& other) noexcept; + + response::IdType id; +}; + +struct [[nodiscard("unnecessary construction")]] IncludeNullableSelfInput +{ + explicit IncludeNullableSelfInput() noexcept; + explicit IncludeNullableSelfInput( + std::unique_ptr selfArg) noexcept; + IncludeNullableSelfInput(const IncludeNullableSelfInput& other); + IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept; + ~IncludeNullableSelfInput(); + + IncludeNullableSelfInput& operator=(const IncludeNullableSelfInput& other); + IncludeNullableSelfInput& operator=(IncludeNullableSelfInput&& other) noexcept; + + std::unique_ptr self; +}; + +struct [[nodiscard("unnecessary construction")]] IncludeNonNullableListSelfInput +{ + explicit IncludeNonNullableListSelfInput() noexcept; + explicit IncludeNonNullableListSelfInput( + std::vector selvesArg) noexcept; + IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other); + IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept; + ~IncludeNonNullableListSelfInput(); + + IncludeNonNullableListSelfInput& operator=(const IncludeNonNullableListSelfInput& other); + IncludeNonNullableListSelfInput& operator=(IncludeNonNullableListSelfInput&& other) noexcept; + + std::vector selves; +}; + +struct [[nodiscard("unnecessary construction")]] StringOperationFilterInput +{ + explicit StringOperationFilterInput() noexcept; + explicit StringOperationFilterInput( + std::optional> and_Arg, + std::optional> or_Arg, + std::optional equalArg, + std::optional notEqualArg, + std::optional containsArg, + std::optional notContainsArg, + std::optional> inArg, + std::optional> notInArg, + std::optional startsWithArg, + std::optional notStartsWithArg, + std::optional endsWithArg, + std::optional notEndsWithArg) noexcept; + StringOperationFilterInput(const StringOperationFilterInput& other); + StringOperationFilterInput(StringOperationFilterInput&& other) noexcept; + ~StringOperationFilterInput(); + + StringOperationFilterInput& operator=(const StringOperationFilterInput& other); + StringOperationFilterInput& operator=(StringOperationFilterInput&& other) noexcept; + + std::optional> and_; + std::optional> or_; + std::optional equal; + std::optional notEqual; + std::optional contains; + std::optional notContains; + std::optional> in; + std::optional> notIn; + std::optional startsWith; + std::optional notStartsWith; + std::optional endsWith; + std::optional notEndsWith; +}; + +struct [[nodiscard("unnecessary construction")]] SecondNestedInput +{ + explicit SecondNestedInput() noexcept; + explicit SecondNestedInput( + response::IdType idArg, + ThirdNestedInput thirdArg) noexcept; + SecondNestedInput(const SecondNestedInput& other); + SecondNestedInput(SecondNestedInput&& other) noexcept; + ~SecondNestedInput(); + + SecondNestedInput& operator=(const SecondNestedInput& other); + SecondNestedInput& operator=(SecondNestedInput&& other) noexcept; + + response::IdType id; + ThirdNestedInput third; +}; + +struct [[nodiscard("unnecessary construction")]] ForwardDeclaredInput +{ + explicit ForwardDeclaredInput() noexcept; + explicit ForwardDeclaredInput( + std::unique_ptr nullableSelfArg, + IncludeNonNullableListSelfInput listSelvesArg) noexcept; + ForwardDeclaredInput(const ForwardDeclaredInput& other); + ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept; + ~ForwardDeclaredInput(); + + ForwardDeclaredInput& operator=(const ForwardDeclaredInput& other); + ForwardDeclaredInput& operator=(ForwardDeclaredInput&& other) noexcept; + + std::unique_ptr nullableSelf; + IncludeNonNullableListSelfInput listSelves; +}; + +struct [[nodiscard("unnecessary construction")]] FirstNestedInput +{ + explicit FirstNestedInput() noexcept; + explicit FirstNestedInput( + response::IdType idArg, + SecondNestedInput secondArg, + ThirdNestedInput thirdArg) noexcept; + FirstNestedInput(const FirstNestedInput& other); + FirstNestedInput(FirstNestedInput&& other) noexcept; + ~FirstNestedInput(); + + FirstNestedInput& operator=(const FirstNestedInput& other); + FirstNestedInput& operator=(FirstNestedInput&& other) noexcept; + + response::IdType id; + SecondNestedInput second; + ThirdNestedInput third; +}; + +} // namespace graphql::today + +#endif // TODAYSHAREDTYPES_H diff --git a/samples/today/schema/TodaySharedTypes.ixx b/samples/today/schema/TodaySharedTypes.ixx new file mode 100644 index 00000000..ee76a95a --- /dev/null +++ b/samples/today/schema/TodaySharedTypes.ixx @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TodaySharedTypes.h" + +export module GraphQL.Today.TodaySharedTypes; + +export namespace graphql::today { + +using today::TaskState; +using today::getTaskStateNames; +using today::getTaskStateValues; + +using today::CompleteTaskInput; +using today::ThirdNestedInput; +using today::FourthNestedInput; +using today::IncludeNullableSelfInput; +using today::IncludeNonNullableListSelfInput; +using today::StringOperationFilterInput; +using today::SecondNestedInput; +using today::ForwardDeclaredInput; +using today::FirstNestedInput; + +} // namespace graphql::today diff --git a/samples/validation/schema/ValidationSchema.h b/samples/validation/schema/ValidationSchema.h index 9f6be1d3..0d6a6041 100644 --- a/samples/validation/schema/ValidationSchema.h +++ b/samples/validation/schema/ValidationSchema.h @@ -14,6 +14,8 @@ #include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" +#include "ValidationSharedTypes.h" + #include #include #include @@ -25,76 +27,6 @@ static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: namespace graphql { namespace validation { - -enum class [[nodiscard("unnecessary conversion")]] DogCommand -{ - SIT, - DOWN, - HEEL -}; - -[[nodiscard("unnecessary call")]] constexpr auto getDogCommandNames() noexcept -{ - using namespace std::literals; - - return std::array { - R"gql(SIT)gql"sv, - R"gql(DOWN)gql"sv, - R"gql(HEEL)gql"sv - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto getDogCommandValues() noexcept -{ - using namespace std::literals; - - return std::array, 3> { - std::make_pair(R"gql(SIT)gql"sv, DogCommand::SIT), - std::make_pair(R"gql(DOWN)gql"sv, DogCommand::DOWN), - std::make_pair(R"gql(HEEL)gql"sv, DogCommand::HEEL) - }; -} - -enum class [[nodiscard("unnecessary conversion")]] CatCommand -{ - JUMP -}; - -[[nodiscard("unnecessary call")]] constexpr auto getCatCommandNames() noexcept -{ - using namespace std::literals; - - return std::array { - R"gql(JUMP)gql"sv - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto getCatCommandValues() noexcept -{ - using namespace std::literals; - - return std::array, 1> { - std::make_pair(R"gql(JUMP)gql"sv, CatCommand::JUMP) - }; -} - -struct [[nodiscard("unnecessary construction")]] ComplexInput -{ - explicit ComplexInput() noexcept; - explicit ComplexInput( - std::optional nameArg, - std::optional ownerArg) noexcept; - ComplexInput(const ComplexInput& other); - ComplexInput(ComplexInput&& other) noexcept; - ~ComplexInput(); - - ComplexInput& operator=(const ComplexInput& other); - ComplexInput& operator=(ComplexInput&& other) noexcept; - - std::optional name; - std::optional owner; -}; - namespace object { class Sentient; diff --git a/samples/validation/schema/ValidationSchema.ixx b/samples/validation/schema/ValidationSchema.ixx index 0501c3ec..32a656ad 100644 --- a/samples/validation/schema/ValidationSchema.ixx +++ b/samples/validation/schema/ValidationSchema.ixx @@ -9,6 +9,8 @@ module; export module GraphQL.Validation.ValidationSchema; +export import GraphQL.Validation.ValidationSharedTypes; + export import GraphQL.Validation.SentientObject; export import GraphQL.Validation.PetObject; export import GraphQL.Validation.NodeObject; @@ -29,16 +31,6 @@ export import GraphQL.Validation.ArgumentsObject; export namespace graphql::validation { -using validation::DogCommand; -using validation::getDogCommandNames; -using validation::getDogCommandValues; - -using validation::CatCommand; -using validation::getCatCommandNames; -using validation::getCatCommandValues; - -using validation::ComplexInput; - using validation::Operations; using validation::AddSentientDetails; diff --git a/samples/validation/schema/ValidationSharedTypes.h b/samples/validation/schema/ValidationSharedTypes.h new file mode 100644 index 00000000..71aa4da4 --- /dev/null +++ b/samples/validation/schema/ValidationSharedTypes.h @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef VALIDATIONSHAREDTYPES_H +#define VALIDATIONSHAREDTYPES_H + +#include "graphqlservice/GraphQLResponse.h" + +#include "graphqlservice/internal/Version.h" + +#include +#include +#include +#include +#include +#include + +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); + +namespace graphql::validation { + +enum class [[nodiscard("unnecessary conversion")]] DogCommand +{ + SIT, + DOWN, + HEEL +}; + +[[nodiscard("unnecessary call")]] constexpr auto getDogCommandNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(SIT)gql"sv, + R"gql(DOWN)gql"sv, + R"gql(HEEL)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getDogCommandValues() noexcept +{ + using namespace std::literals; + + return std::array, 3> { + std::make_pair(R"gql(SIT)gql"sv, DogCommand::SIT), + std::make_pair(R"gql(DOWN)gql"sv, DogCommand::DOWN), + std::make_pair(R"gql(HEEL)gql"sv, DogCommand::HEEL) + }; +} + +enum class [[nodiscard("unnecessary conversion")]] CatCommand +{ + JUMP +}; + +[[nodiscard("unnecessary call")]] constexpr auto getCatCommandNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(JUMP)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getCatCommandValues() noexcept +{ + using namespace std::literals; + + return std::array, 1> { + std::make_pair(R"gql(JUMP)gql"sv, CatCommand::JUMP) + }; +} + +struct [[nodiscard("unnecessary construction")]] ComplexInput +{ + explicit ComplexInput() noexcept; + explicit ComplexInput( + std::optional nameArg, + std::optional ownerArg) noexcept; + ComplexInput(const ComplexInput& other); + ComplexInput(ComplexInput&& other) noexcept; + ~ComplexInput(); + + ComplexInput& operator=(const ComplexInput& other); + ComplexInput& operator=(ComplexInput&& other) noexcept; + + std::optional name; + std::optional owner; +}; + +} // namespace graphql::validation + +#endif // VALIDATIONSHAREDTYPES_H diff --git a/samples/validation/schema/ValidationSharedTypes.ixx b/samples/validation/schema/ValidationSharedTypes.ixx new file mode 100644 index 00000000..9dbcfe15 --- /dev/null +++ b/samples/validation/schema/ValidationSharedTypes.ixx @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ValidationSharedTypes.h" + +export module GraphQL.Validation.ValidationSharedTypes; + +export namespace graphql::validation { + +using validation::DogCommand; +using validation::getDogCommandNames; +using validation::getDogCommandValues; + +using validation::CatCommand; +using validation::getCatCommandNames; +using validation::getCatCommandValues; + +using validation::ComplexInput; + +} // namespace graphql::validation diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 7bf1af1d..f528477d 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -40,8 +40,10 @@ Generator::Generator(SchemaOptions&& schemaOptions, GeneratorOptions&& options) , _options(std::move(options)) , _headerDir(getHeaderDir()) , _sourceDir(getSourceDir()) - , _headerPath(getHeaderPath()) - , _modulePath(getModulePath()) + , _schemaHeaderPath(getSchemaHeaderPath()) + , _schemaModulePath(getSchemaModulePath()) + , _sharedTypesHeaderPath(getSharedTypesHeaderPath()) + , _sharedTypesModulePath(getSharedTypesModulePath()) , _sourcePath(getSourcePath()) { } @@ -70,7 +72,7 @@ std::string Generator::getSourceDir() const noexcept } } -std::string Generator::getHeaderPath() const noexcept +std::string Generator::getSchemaHeaderPath() const noexcept { std::filesystem::path fullPath { _headerDir }; @@ -78,7 +80,7 @@ std::string Generator::getHeaderPath() const noexcept return fullPath.string(); } -std::string Generator::getModulePath() const noexcept +std::string Generator::getSchemaModulePath() const noexcept { std::filesystem::path fullPath { _headerDir }; @@ -86,6 +88,22 @@ std::string Generator::getModulePath() const noexcept return fullPath.string(); } +std::string Generator::getSharedTypesHeaderPath() const noexcept +{ + std::filesystem::path fullPath { _headerDir }; + + fullPath /= (std::string { _loader.getFilenamePrefix() } + "SharedTypes.h"); + return fullPath.string(); +} + +std::string Generator::getSharedTypesModulePath() const noexcept +{ + std::filesystem::path fullPath { _headerDir }; + + fullPath /= (std::string { _loader.getFilenamePrefix() } + "SharedTypes.ixx"); + return fullPath.string(); +} + std::string Generator::getSourcePath() const noexcept { std::filesystem::path fullPath { _sourceDir }; @@ -98,14 +116,24 @@ std::vector Generator::Build() const noexcept { std::vector builtFiles; - if (outputHeader() && _options.verbose) + if (outputSharedTypesHeader() && _options.verbose) + { + builtFiles.push_back(_sharedTypesHeaderPath); + } + + if (outputSharedTypesModule() && _options.verbose) + { + builtFiles.push_back(_sharedTypesModulePath); + } + + if (outputSchemaHeader() && _options.verbose) { - builtFiles.push_back(_headerPath); + builtFiles.push_back(_schemaHeaderPath); } - if (outputModule() && _options.verbose) + if (outputSchemaModule() && _options.verbose) { - builtFiles.push_back(_modulePath); + builtFiles.push_back(_schemaModulePath); } if (outputSource()) @@ -123,18 +151,28 @@ std::vector Generator::Build() const noexcept return builtFiles; } -bool Generator::outputHeader() const noexcept +bool Generator::outputSchemaHeader() const noexcept { - std::ofstream headerFile(_headerPath, std::ios_base::trunc); + std::ofstream headerFile(_schemaHeaderPath, std::ios_base::trunc); IncludeGuardScope includeGuard { headerFile, - std::filesystem::path(_headerPath).filename().string() }; + std::filesystem::path(_schemaHeaderPath).filename().string() }; headerFile << R"cpp(#include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" #include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" +)cpp"; + + if (!_loader.getEnumTypes().empty() || !_loader.getInputTypes().empty()) + { + headerFile << R"cpp( +#include ")cpp" << _loader.getFilenamePrefix() + << R"cpp(SharedTypes.h" +)cpp"; + } + headerFile << R"cpp( #include #include #include @@ -157,209 +195,6 @@ static_assert(graphql::internal::MinorVersion == )cpp" NamespaceScope objectNamespace { headerFile, "object", true }; PendingBlankLine pendingSeparator { headerFile }; - if (!_loader.getEnumTypes().empty()) - { - pendingSeparator.reset(); - - for (const auto& enumType : _loader.getEnumTypes()) - { - headerFile << R"cpp(enum class )cpp"; - - if (!_loader.isIntrospection()) - { - headerFile << R"cpp([[nodiscard("unnecessary conversion")]] )cpp"; - } - - headerFile << enumType.cppType << R"cpp( -{ -)cpp"; - - bool firstValue = true; - - for (const auto& value : enumType.values) - { - if (!firstValue) - { - headerFile << R"cpp(, -)cpp"; - } - - firstValue = false; - headerFile << R"cpp( )cpp" << value.cppValue; - } - headerFile << R"cpp( -}; - -)cpp"; - - headerFile << R"cpp([[nodiscard("unnecessary call")]] constexpr auto get)cpp" - << enumType.cppType << R"cpp(Names() noexcept -{ - using namespace std::literals; - - return std::array { -)cpp"; - - firstValue = true; - - for (const auto& value : enumType.values) - { - if (!firstValue) - { - headerFile << R"cpp(, -)cpp"; - } - - firstValue = false; - headerFile << R"cpp( R"gql()cpp" << value.value << R"cpp()gql"sv)cpp"; - } - - headerFile << R"cpp( - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto get)cpp" - << enumType.cppType << R"cpp(Values() noexcept -{ - using namespace std::literals; - - return std::array, )cpp" << enumType.values.size() << R"cpp(> { -)cpp"; - - std::vector> sortedValues( - enumType.values.size()); - - std::ranges::transform(enumType.values, - sortedValues.begin(), - [](const auto& value) noexcept { - return std::make_pair(value.value, value.cppValue); - }); - std::ranges::sort(sortedValues, [](const auto& lhs, const auto& rhs) noexcept { - return internal::shorter_or_less {}(lhs.first, rhs.first); - }); - - firstValue = true; - - for (const auto& [enumName, enumValue] : sortedValues) - { - if (!firstValue) - { - headerFile << R"cpp(, -)cpp"; - } - - firstValue = false; - headerFile << R"cpp( std::make_pair(R"gql()cpp" << enumName - << R"cpp()gql"sv, )cpp" << enumType.cppType << R"cpp(::)cpp" << enumValue - << R"cpp())cpp"; - } - - headerFile << R"cpp( - }; -} - -)cpp"; - } - } - - if (!_loader.getInputTypes().empty()) - { - pendingSeparator.reset(); - - std::unordered_set forwardDeclared; - const auto introspectionExport = - (_loader.isIntrospection() ? "GRAPHQLSERVICE_EXPORT "sv : ""sv); - - // Output the full declarations - for (const auto& inputType : _loader.getInputTypes()) - { - forwardDeclared.insert(inputType.cppType); - - if (!inputType.declarations.empty()) - { - // Forward declare nullable dependencies - for (auto declaration : inputType.declarations) - { - if (forwardDeclared.insert(declaration).second) - { - headerFile << R"cpp(struct )cpp" << declaration << R"cpp(; -)cpp"; - pendingSeparator.add(); - } - } - - pendingSeparator.reset(); - } - - headerFile << R"cpp(struct [[nodiscard("unnecessary construction")]] )cpp" - << inputType.cppType << R"cpp( -{ - )cpp" << introspectionExport - << R"cpp(explicit )cpp" << inputType.cppType << R"cpp(()cpp"; - - bool firstField = true; - - for (const auto& inputField : inputType.fields) - { - if (firstField) - { - headerFile << R"cpp() noexcept; - explicit )cpp" << inputType.cppType - << R"cpp(()cpp"; - } - else - { - headerFile << R"cpp(,)cpp"; - } - - firstField = false; - - const auto inputCppType = _loader.getInputCppType(inputField); - - headerFile << R"cpp( - )cpp" << inputCppType - << R"cpp( )cpp" << inputField.cppName << R"cpp(Arg)cpp"; - } - - headerFile << R"cpp() noexcept; - )cpp" << introspectionExport - << inputType.cppType << R"cpp((const )cpp" << inputType.cppType - << R"cpp(& other); - )cpp" << introspectionExport - << inputType.cppType << R"cpp(()cpp" << inputType.cppType - << R"cpp(&& other) noexcept; - ~)cpp" << inputType.cppType - << R"cpp((); - - )cpp" << introspectionExport - << inputType.cppType << R"cpp(& operator=(const )cpp" << inputType.cppType - << R"cpp(& other); - )cpp" << introspectionExport - << inputType.cppType << R"cpp(& operator=()cpp" << inputType.cppType - << R"cpp(&& other) noexcept; -)cpp"; - - firstField = true; - - for (const auto& inputField : inputType.fields) - { - if (firstField) - { - headerFile << std::endl; - } - - firstField = false; - - headerFile << getFieldDeclaration(inputField); - } - headerFile << R"cpp(}; - -)cpp"; - } - } - if (!_loader.getInterfaceTypes().empty()) { objectNamespace.enter(); @@ -671,9 +506,9 @@ GRAPHQLSERVICE_EXPORT )cpp" << _loader.getSchemaNamespace() return true; } -bool Generator::outputModule() const noexcept +bool Generator::outputSchemaModule() const noexcept { - std::ofstream moduleFile(_modulePath, std::ios_base::trunc); + std::ofstream moduleFile(_schemaModulePath, std::ios_base::trunc); const auto schemaNamespace = std::format(R"cpp(graphql::{})cpp", _loader.getSchemaNamespace()); moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. @@ -692,6 +527,15 @@ export module GraphQL.)cpp" R"cpp(Schema; )cpp"; + if (!_loader.getEnumTypes().empty() || !_loader.getInputTypes().empty()) + { + moduleFile << R"cpp( +export import GraphQL.)cpp" + << _loader.getFilenamePrefix() << R"cpp(.)cpp" << _loader.getFilenamePrefix() << + R"cpp(SharedTypes; +)cpp"; + } + PendingBlankLine pendingSeparator { moduleFile }; if (!_loader.getInterfaceTypes().empty()) @@ -737,54 +581,23 @@ export )cpp"; pendingSeparator.add(); - if (!_loader.getEnumTypes().empty()) + if (!_loader.isIntrospection()) { pendingSeparator.reset(); - for (const auto& enumType : _loader.getEnumTypes()) - { - moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" - << enumType.cppType << R"cpp(; -using )cpp" << _loader.getSchemaNamespace() - << R"cpp(::get)cpp" << enumType.cppType << R"cpp(Names; -using )cpp" << _loader.getSchemaNamespace() - << R"cpp(::get)cpp" << enumType.cppType << R"cpp(Values; + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Operations; )cpp"; - } } - if (!_loader.getInputTypes().empty()) + if (!_loader.getInterfaceTypes().empty()) { pendingSeparator.reset(); - for (const auto& inputType : _loader.getInputTypes()) + for (const auto& interfaceType : _loader.getInterfaceTypes()) { - moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" - << inputType.cppType << R"cpp(; -)cpp"; - } - - moduleFile << std::endl; - } - - if (!_loader.isIntrospection()) - { - pendingSeparator.reset(); - - moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Operations; - -)cpp"; - } - - if (!_loader.getInterfaceTypes().empty()) - { - pendingSeparator.reset(); - - for (const auto& interfaceType : _loader.getInterfaceTypes()) - { - moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Add)cpp" - << interfaceType.cppType << R"cpp(Details; + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Add)cpp" + << interfaceType.cppType << R"cpp(Details; )cpp"; } } @@ -833,6 +646,319 @@ using )cpp" << _loader.getSchemaNamespace() return true; } +bool Generator::outputSharedTypesHeader() const noexcept +{ + if (_loader.getEnumTypes().empty() && _loader.getInputTypes().empty()) + { + return false; + } + + std::ofstream headerFile(_sharedTypesHeaderPath, std::ios_base::trunc); + IncludeGuardScope includeGuard { headerFile, + std::filesystem::path(_sharedTypesHeaderPath).filename().string() }; + + headerFile << R"cpp(#include "graphqlservice/GraphQLResponse.h" + +#include "graphqlservice/internal/Version.h" + +#include +#include +#include +#include +#include +#include + +// Check if the library version is compatible with schemagen )cpp" + << graphql::internal::MajorVersion << R"cpp(.)cpp" << graphql::internal::MinorVersion + << R"cpp(.0 +static_assert(graphql::internal::MajorVersion == )cpp" + << graphql::internal::MajorVersion + << R"cpp(, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == )cpp" + << graphql::internal::MinorVersion + << R"cpp(, "regenerate with schemagen: minor version mismatch"); + +)cpp"; + + const auto schemaNamespace = std::format(R"cpp(graphql::{})cpp", _loader.getSchemaNamespace()); + NamespaceScope schemaNamespaceScope { headerFile, schemaNamespace }; + PendingBlankLine pendingSeparator { headerFile }; + + if (!_loader.getEnumTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& enumType : _loader.getEnumTypes()) + { + headerFile << R"cpp(enum class )cpp"; + + if (!_loader.isIntrospection()) + { + headerFile << R"cpp([[nodiscard("unnecessary conversion")]] )cpp"; + } + + headerFile << enumType.cppType << R"cpp( +{ +)cpp"; + + bool firstValue = true; + + for (const auto& value : enumType.values) + { + if (!firstValue) + { + headerFile << R"cpp(, +)cpp"; + } + + firstValue = false; + headerFile << R"cpp( )cpp" << value.cppValue; + } + headerFile << R"cpp( +}; + +)cpp"; + + headerFile << R"cpp([[nodiscard("unnecessary call")]] constexpr auto get)cpp" + << enumType.cppType << R"cpp(Names() noexcept +{ + using namespace std::literals; + + return std::array { +)cpp"; + + firstValue = true; + + for (const auto& value : enumType.values) + { + if (!firstValue) + { + headerFile << R"cpp(, +)cpp"; + } + + firstValue = false; + headerFile << R"cpp( R"gql()cpp" << value.value << R"cpp()gql"sv)cpp"; + } + + headerFile << R"cpp( + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto get)cpp" + << enumType.cppType << R"cpp(Values() noexcept +{ + using namespace std::literals; + + return std::array, )cpp" << enumType.values.size() << R"cpp(> { +)cpp"; + + std::vector> sortedValues( + enumType.values.size()); + + std::ranges::transform(enumType.values, + sortedValues.begin(), + [](const auto& value) noexcept { + return std::make_pair(value.value, value.cppValue); + }); + std::ranges::sort(sortedValues, [](const auto& lhs, const auto& rhs) noexcept { + return internal::shorter_or_less {}(lhs.first, rhs.first); + }); + + firstValue = true; + + for (const auto& [enumName, enumValue] : sortedValues) + { + if (!firstValue) + { + headerFile << R"cpp(, +)cpp"; + } + + firstValue = false; + headerFile << R"cpp( std::make_pair(R"gql()cpp" << enumName + << R"cpp()gql"sv, )cpp" << enumType.cppType << R"cpp(::)cpp" << enumValue + << R"cpp())cpp"; + } + + headerFile << R"cpp( + }; +} + +)cpp"; + } + } + + if (!_loader.getInputTypes().empty()) + { + pendingSeparator.reset(); + + std::unordered_set forwardDeclared; + const auto introspectionExport = + (_loader.isIntrospection() ? "GRAPHQLSERVICE_EXPORT "sv : ""sv); + + // Output the full declarations + for (const auto& inputType : _loader.getInputTypes()) + { + forwardDeclared.insert(inputType.cppType); + + if (!inputType.declarations.empty()) + { + // Forward declare nullable dependencies + for (auto declaration : inputType.declarations) + { + if (forwardDeclared.insert(declaration).second) + { + headerFile << R"cpp(struct )cpp" << declaration << R"cpp(; +)cpp"; + pendingSeparator.add(); + } + } + + pendingSeparator.reset(); + } + + headerFile << R"cpp(struct [[nodiscard("unnecessary construction")]] )cpp" + << inputType.cppType << R"cpp( +{ + )cpp" << introspectionExport + << R"cpp(explicit )cpp" << inputType.cppType << R"cpp(()cpp"; + + bool firstField = true; + + for (const auto& inputField : inputType.fields) + { + if (firstField) + { + headerFile << R"cpp() noexcept; + explicit )cpp" << inputType.cppType + << R"cpp(()cpp"; + } + else + { + headerFile << R"cpp(,)cpp"; + } + + firstField = false; + + const auto inputCppType = _loader.getInputCppType(inputField); + + headerFile << R"cpp( + )cpp" << inputCppType + << R"cpp( )cpp" << inputField.cppName << R"cpp(Arg)cpp"; + } + + headerFile << R"cpp() noexcept; + )cpp" << introspectionExport + << inputType.cppType << R"cpp((const )cpp" << inputType.cppType + << R"cpp(& other); + )cpp" << introspectionExport + << inputType.cppType << R"cpp(()cpp" << inputType.cppType + << R"cpp(&& other) noexcept; + ~)cpp" << inputType.cppType + << R"cpp((); + + )cpp" << introspectionExport + << inputType.cppType << R"cpp(& operator=(const )cpp" << inputType.cppType + << R"cpp(& other); + )cpp" << introspectionExport + << inputType.cppType << R"cpp(& operator=()cpp" << inputType.cppType + << R"cpp(&& other) noexcept; +)cpp"; + + firstField = true; + + for (const auto& inputField : inputType.fields) + { + if (firstField) + { + headerFile << std::endl; + } + + firstField = false; + + headerFile << getFieldDeclaration(inputField); + } + headerFile << R"cpp(}; + +)cpp"; + } + } + + return true; +} + +bool Generator::outputSharedTypesModule() const noexcept +{ + if (_loader.getEnumTypes().empty() && _loader.getInputTypes().empty()) + { + return false; + } + + std::ofstream moduleFile(_sharedTypesModulePath, std::ios_base::trunc); + const auto schemaNamespace = std::format(R"cpp(graphql::{})cpp", _loader.getSchemaNamespace()); + + moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include ")cpp" << _loader.getFilenamePrefix() + << + R"cpp(SharedTypes.h" + +export module GraphQL.)cpp" + << _loader.getFilenamePrefix() << R"cpp(.)cpp" << _loader.getFilenamePrefix() << + R"cpp(SharedTypes; +)cpp"; + + PendingBlankLine pendingSeparator { moduleFile }; + + moduleFile << R"cpp( +export )cpp"; + + NamespaceScope graphqlNamespace { moduleFile, schemaNamespace }; + + pendingSeparator.add(); + + if (!_loader.getEnumTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& enumType : _loader.getEnumTypes()) + { + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" + << enumType.cppType << R"cpp(; +using )cpp" << _loader.getSchemaNamespace() + << R"cpp(::get)cpp" << enumType.cppType << R"cpp(Names; +using )cpp" << _loader.getSchemaNamespace() + << R"cpp(::get)cpp" << enumType.cppType << R"cpp(Values; + +)cpp"; + } + } + + if (!_loader.getInputTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& inputType : _loader.getInputTypes()) + { + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" + << inputType.cppType << R"cpp(; +)cpp"; + } + + moduleFile << std::endl; + } + + return true; +} + void Generator::outputInterfaceDeclaration(std::ostream& headerFile, std::string_view cppType) const { headerFile @@ -1459,7 +1585,7 @@ bool Generator::outputSource() const noexcept if (_loader.getOperationTypes().empty()) { // Normally this would be included by each of the operation object headers. - sourceFile << R"cpp(#include ")cpp" << getHeaderPath() << R"cpp(" + sourceFile << R"cpp(#include ")cpp" << getSchemaHeaderPath() << R"cpp(" )cpp"; } else @@ -2292,7 +2418,8 @@ Operations::Operations()cpp"; )cpp"; } sourceFile << R"cpp(}, )cpp" - << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") << R"cpp()); + << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") + << R"cpp()); )cpp"; } } @@ -3224,7 +3351,7 @@ std::vector Generator::outputSeparateFiles() const noexcept IncludeGuardScope includeGuard { headerFile, headerFilename }; headerFile << R"cpp(#include ")cpp" - << std::filesystem::path(_headerPath).filename().string() << R"cpp(" + << std::filesystem::path(_schemaHeaderPath).filename().string() << R"cpp(" )cpp"; @@ -3308,7 +3435,7 @@ using namespace std::literals; IncludeGuardScope includeGuard { headerFile, headerFilename }; headerFile << R"cpp(#include ")cpp" - << std::filesystem::path(_headerPath).filename().string() << R"cpp(" + << std::filesystem::path(_schemaHeaderPath).filename().string() << R"cpp(" )cpp"; @@ -3412,7 +3539,7 @@ using namespace std::literals; IncludeGuardScope includeGuard { headerFile, headerFilename }; headerFile << R"cpp(#include ")cpp" - << std::filesystem::path(_headerPath).filename().string() << R"cpp(" + << std::filesystem::path(_schemaHeaderPath).filename().string() << R"cpp(" )cpp"; diff --git a/src/introspection/IntrospectionSchema.h b/src/introspection/IntrospectionSchema.h index b754e4ad..3ea811b0 100644 --- a/src/introspection/IntrospectionSchema.h +++ b/src/introspection/IntrospectionSchema.h @@ -14,6 +14,8 @@ #include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" +#include "IntrospectionSharedTypes.h" + #include #include #include @@ -25,128 +27,6 @@ static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: namespace graphql { namespace introspection { - -enum class TypeKind -{ - SCALAR, - OBJECT, - INTERFACE, - UNION, - ENUM, - INPUT_OBJECT, - LIST, - NON_NULL -}; - -[[nodiscard("unnecessary call")]] constexpr auto getTypeKindNames() noexcept -{ - using namespace std::literals; - - return std::array { - R"gql(SCALAR)gql"sv, - R"gql(OBJECT)gql"sv, - R"gql(INTERFACE)gql"sv, - R"gql(UNION)gql"sv, - R"gql(ENUM)gql"sv, - R"gql(INPUT_OBJECT)gql"sv, - R"gql(LIST)gql"sv, - R"gql(NON_NULL)gql"sv - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto getTypeKindValues() noexcept -{ - using namespace std::literals; - - return std::array, 8> { - std::make_pair(R"gql(ENUM)gql"sv, TypeKind::ENUM), - std::make_pair(R"gql(LIST)gql"sv, TypeKind::LIST), - std::make_pair(R"gql(UNION)gql"sv, TypeKind::UNION), - std::make_pair(R"gql(OBJECT)gql"sv, TypeKind::OBJECT), - std::make_pair(R"gql(SCALAR)gql"sv, TypeKind::SCALAR), - std::make_pair(R"gql(NON_NULL)gql"sv, TypeKind::NON_NULL), - std::make_pair(R"gql(INTERFACE)gql"sv, TypeKind::INTERFACE), - std::make_pair(R"gql(INPUT_OBJECT)gql"sv, TypeKind::INPUT_OBJECT) - }; -} - -enum class DirectiveLocation -{ - QUERY, - MUTATION, - SUBSCRIPTION, - FIELD, - FRAGMENT_DEFINITION, - FRAGMENT_SPREAD, - INLINE_FRAGMENT, - VARIABLE_DEFINITION, - SCHEMA, - SCALAR, - OBJECT, - FIELD_DEFINITION, - ARGUMENT_DEFINITION, - INTERFACE, - UNION, - ENUM, - ENUM_VALUE, - INPUT_OBJECT, - INPUT_FIELD_DEFINITION -}; - -[[nodiscard("unnecessary call")]] constexpr auto getDirectiveLocationNames() noexcept -{ - using namespace std::literals; - - return std::array { - R"gql(QUERY)gql"sv, - R"gql(MUTATION)gql"sv, - R"gql(SUBSCRIPTION)gql"sv, - R"gql(FIELD)gql"sv, - R"gql(FRAGMENT_DEFINITION)gql"sv, - R"gql(FRAGMENT_SPREAD)gql"sv, - R"gql(INLINE_FRAGMENT)gql"sv, - R"gql(VARIABLE_DEFINITION)gql"sv, - R"gql(SCHEMA)gql"sv, - R"gql(SCALAR)gql"sv, - R"gql(OBJECT)gql"sv, - R"gql(FIELD_DEFINITION)gql"sv, - R"gql(ARGUMENT_DEFINITION)gql"sv, - R"gql(INTERFACE)gql"sv, - R"gql(UNION)gql"sv, - R"gql(ENUM)gql"sv, - R"gql(ENUM_VALUE)gql"sv, - R"gql(INPUT_OBJECT)gql"sv, - R"gql(INPUT_FIELD_DEFINITION)gql"sv - }; -} - -[[nodiscard("unnecessary call")]] constexpr auto getDirectiveLocationValues() noexcept -{ - using namespace std::literals; - - return std::array, 19> { - std::make_pair(R"gql(ENUM)gql"sv, DirectiveLocation::ENUM), - std::make_pair(R"gql(FIELD)gql"sv, DirectiveLocation::FIELD), - std::make_pair(R"gql(QUERY)gql"sv, DirectiveLocation::QUERY), - std::make_pair(R"gql(UNION)gql"sv, DirectiveLocation::UNION), - std::make_pair(R"gql(OBJECT)gql"sv, DirectiveLocation::OBJECT), - std::make_pair(R"gql(SCALAR)gql"sv, DirectiveLocation::SCALAR), - std::make_pair(R"gql(SCHEMA)gql"sv, DirectiveLocation::SCHEMA), - std::make_pair(R"gql(MUTATION)gql"sv, DirectiveLocation::MUTATION), - std::make_pair(R"gql(INTERFACE)gql"sv, DirectiveLocation::INTERFACE), - std::make_pair(R"gql(ENUM_VALUE)gql"sv, DirectiveLocation::ENUM_VALUE), - std::make_pair(R"gql(INPUT_OBJECT)gql"sv, DirectiveLocation::INPUT_OBJECT), - std::make_pair(R"gql(SUBSCRIPTION)gql"sv, DirectiveLocation::SUBSCRIPTION), - std::make_pair(R"gql(FRAGMENT_SPREAD)gql"sv, DirectiveLocation::FRAGMENT_SPREAD), - std::make_pair(R"gql(INLINE_FRAGMENT)gql"sv, DirectiveLocation::INLINE_FRAGMENT), - std::make_pair(R"gql(FIELD_DEFINITION)gql"sv, DirectiveLocation::FIELD_DEFINITION), - std::make_pair(R"gql(ARGUMENT_DEFINITION)gql"sv, DirectiveLocation::ARGUMENT_DEFINITION), - std::make_pair(R"gql(FRAGMENT_DEFINITION)gql"sv, DirectiveLocation::FRAGMENT_DEFINITION), - std::make_pair(R"gql(VARIABLE_DEFINITION)gql"sv, DirectiveLocation::VARIABLE_DEFINITION), - std::make_pair(R"gql(INPUT_FIELD_DEFINITION)gql"sv, DirectiveLocation::INPUT_FIELD_DEFINITION) - }; -} - class Schema; class Type; class Field; diff --git a/src/introspection/IntrospectionSchema.ixx b/src/introspection/IntrospectionSchema.ixx index 45f3f14a..8ce51120 100644 --- a/src/introspection/IntrospectionSchema.ixx +++ b/src/introspection/IntrospectionSchema.ixx @@ -9,6 +9,8 @@ module; export module GraphQL.Introspection.IntrospectionSchema; +export import GraphQL.Introspection.IntrospectionSharedTypes; + export import GraphQL.Introspection.SchemaObject; export import GraphQL.Introspection.TypeObject; export import GraphQL.Introspection.FieldObject; @@ -18,14 +20,6 @@ export import GraphQL.Introspection.DirectiveObject; export namespace graphql::introspection { -using introspection::TypeKind; -using introspection::getTypeKindNames; -using introspection::getTypeKindValues; - -using introspection::DirectiveLocation; -using introspection::getDirectiveLocationNames; -using introspection::getDirectiveLocationValues; - using introspection::AddSchemaDetails; using introspection::AddTypeDetails; using introspection::AddFieldDetails; diff --git a/src/introspection/IntrospectionSharedTypes.h b/src/introspection/IntrospectionSharedTypes.h new file mode 100644 index 00000000..63b71c2c --- /dev/null +++ b/src/introspection/IntrospectionSharedTypes.h @@ -0,0 +1,151 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef INTROSPECTIONSHAREDTYPES_H +#define INTROSPECTIONSHAREDTYPES_H + +#include "graphqlservice/GraphQLResponse.h" + +#include "graphqlservice/internal/Version.h" + +#include +#include +#include +#include +#include +#include + +// Check if the library version is compatible with schemagen 5.0.0 +static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); + +namespace graphql::introspection { + +enum class TypeKind +{ + SCALAR, + OBJECT, + INTERFACE, + UNION, + ENUM, + INPUT_OBJECT, + LIST, + NON_NULL +}; + +[[nodiscard("unnecessary call")]] constexpr auto getTypeKindNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(SCALAR)gql"sv, + R"gql(OBJECT)gql"sv, + R"gql(INTERFACE)gql"sv, + R"gql(UNION)gql"sv, + R"gql(ENUM)gql"sv, + R"gql(INPUT_OBJECT)gql"sv, + R"gql(LIST)gql"sv, + R"gql(NON_NULL)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getTypeKindValues() noexcept +{ + using namespace std::literals; + + return std::array, 8> { + std::make_pair(R"gql(ENUM)gql"sv, TypeKind::ENUM), + std::make_pair(R"gql(LIST)gql"sv, TypeKind::LIST), + std::make_pair(R"gql(UNION)gql"sv, TypeKind::UNION), + std::make_pair(R"gql(OBJECT)gql"sv, TypeKind::OBJECT), + std::make_pair(R"gql(SCALAR)gql"sv, TypeKind::SCALAR), + std::make_pair(R"gql(NON_NULL)gql"sv, TypeKind::NON_NULL), + std::make_pair(R"gql(INTERFACE)gql"sv, TypeKind::INTERFACE), + std::make_pair(R"gql(INPUT_OBJECT)gql"sv, TypeKind::INPUT_OBJECT) + }; +} + +enum class DirectiveLocation +{ + QUERY, + MUTATION, + SUBSCRIPTION, + FIELD, + FRAGMENT_DEFINITION, + FRAGMENT_SPREAD, + INLINE_FRAGMENT, + VARIABLE_DEFINITION, + SCHEMA, + SCALAR, + OBJECT, + FIELD_DEFINITION, + ARGUMENT_DEFINITION, + INTERFACE, + UNION, + ENUM, + ENUM_VALUE, + INPUT_OBJECT, + INPUT_FIELD_DEFINITION +}; + +[[nodiscard("unnecessary call")]] constexpr auto getDirectiveLocationNames() noexcept +{ + using namespace std::literals; + + return std::array { + R"gql(QUERY)gql"sv, + R"gql(MUTATION)gql"sv, + R"gql(SUBSCRIPTION)gql"sv, + R"gql(FIELD)gql"sv, + R"gql(FRAGMENT_DEFINITION)gql"sv, + R"gql(FRAGMENT_SPREAD)gql"sv, + R"gql(INLINE_FRAGMENT)gql"sv, + R"gql(VARIABLE_DEFINITION)gql"sv, + R"gql(SCHEMA)gql"sv, + R"gql(SCALAR)gql"sv, + R"gql(OBJECT)gql"sv, + R"gql(FIELD_DEFINITION)gql"sv, + R"gql(ARGUMENT_DEFINITION)gql"sv, + R"gql(INTERFACE)gql"sv, + R"gql(UNION)gql"sv, + R"gql(ENUM)gql"sv, + R"gql(ENUM_VALUE)gql"sv, + R"gql(INPUT_OBJECT)gql"sv, + R"gql(INPUT_FIELD_DEFINITION)gql"sv + }; +} + +[[nodiscard("unnecessary call")]] constexpr auto getDirectiveLocationValues() noexcept +{ + using namespace std::literals; + + return std::array, 19> { + std::make_pair(R"gql(ENUM)gql"sv, DirectiveLocation::ENUM), + std::make_pair(R"gql(FIELD)gql"sv, DirectiveLocation::FIELD), + std::make_pair(R"gql(QUERY)gql"sv, DirectiveLocation::QUERY), + std::make_pair(R"gql(UNION)gql"sv, DirectiveLocation::UNION), + std::make_pair(R"gql(OBJECT)gql"sv, DirectiveLocation::OBJECT), + std::make_pair(R"gql(SCALAR)gql"sv, DirectiveLocation::SCALAR), + std::make_pair(R"gql(SCHEMA)gql"sv, DirectiveLocation::SCHEMA), + std::make_pair(R"gql(MUTATION)gql"sv, DirectiveLocation::MUTATION), + std::make_pair(R"gql(INTERFACE)gql"sv, DirectiveLocation::INTERFACE), + std::make_pair(R"gql(ENUM_VALUE)gql"sv, DirectiveLocation::ENUM_VALUE), + std::make_pair(R"gql(INPUT_OBJECT)gql"sv, DirectiveLocation::INPUT_OBJECT), + std::make_pair(R"gql(SUBSCRIPTION)gql"sv, DirectiveLocation::SUBSCRIPTION), + std::make_pair(R"gql(FRAGMENT_SPREAD)gql"sv, DirectiveLocation::FRAGMENT_SPREAD), + std::make_pair(R"gql(INLINE_FRAGMENT)gql"sv, DirectiveLocation::INLINE_FRAGMENT), + std::make_pair(R"gql(FIELD_DEFINITION)gql"sv, DirectiveLocation::FIELD_DEFINITION), + std::make_pair(R"gql(ARGUMENT_DEFINITION)gql"sv, DirectiveLocation::ARGUMENT_DEFINITION), + std::make_pair(R"gql(FRAGMENT_DEFINITION)gql"sv, DirectiveLocation::FRAGMENT_DEFINITION), + std::make_pair(R"gql(VARIABLE_DEFINITION)gql"sv, DirectiveLocation::VARIABLE_DEFINITION), + std::make_pair(R"gql(INPUT_FIELD_DEFINITION)gql"sv, DirectiveLocation::INPUT_FIELD_DEFINITION) + }; +} + +} // namespace graphql::introspection + +#endif // INTROSPECTIONSHAREDTYPES_H diff --git a/src/introspection/IntrospectionSharedTypes.ixx b/src/introspection/IntrospectionSharedTypes.ixx new file mode 100644 index 00000000..60538148 --- /dev/null +++ b/src/introspection/IntrospectionSharedTypes.ixx @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "IntrospectionSharedTypes.h" + +export module GraphQL.Introspection.IntrospectionSharedTypes; + +export namespace graphql::introspection { + +using introspection::TypeKind; +using introspection::getTypeKindNames; +using introspection::getTypeKindValues; + +using introspection::DirectiveLocation; +using introspection::getDirectiveLocationNames; +using introspection::getDirectiveLocationValues; + +} // namespace graphql::introspection From eee1d66cbbbbfab070ddcb95c306b840d00a57b8 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 24 Sep 2024 09:39:10 -0700 Subject: [PATCH 081/123] fix: split shared types into separate SharedTypes.cpp --- cmake/cppgraphqlgen-update-schema-files.cmake | 3 +- include/SchemaGenerator.h | 9 +- samples/learn/schema/StarWarsSchema.cpp | 135 +--- samples/learn/schema/StarWarsSharedTypes.cpp | 146 ++++ samples/learn/schema/learn_schema_files | 1 + samples/proxy/schema/ProxySchema.cpp | 151 +--- samples/proxy/schema/ProxySharedTypes.cpp | 162 ++++ samples/proxy/schema/proxy_schema_files | 1 + samples/today/nointrospection/TodaySchema.cpp | 719 +---------------- .../nointrospection/TodaySharedTypes.cpp | 736 ++++++++++++++++++ .../today_nointrospection_schema_files | 1 + samples/today/schema/TodaySchema.cpp | 719 +---------------- samples/today/schema/TodaySharedTypes.cpp | 736 ++++++++++++++++++ samples/today/schema/today_schema_files | 1 + .../validation/schema/ValidationSchema.cpp | 195 +---- .../schema/ValidationSharedTypes.cpp | 202 +++++ .../validation/schema/validation_schema_files | 1 + src/SchemaGenerator.cpp | 512 ++++++------ src/introspection/IntrospectionSchema.cpp | 180 +---- .../IntrospectionSharedTypes.cpp | 137 ++++ src/introspection/introspection_schema_files | 1 + 21 files changed, 2492 insertions(+), 2256 deletions(-) create mode 100644 samples/learn/schema/StarWarsSharedTypes.cpp create mode 100644 samples/proxy/schema/ProxySharedTypes.cpp create mode 100644 samples/today/nointrospection/TodaySharedTypes.cpp create mode 100644 samples/today/schema/TodaySharedTypes.cpp create mode 100644 samples/validation/schema/ValidationSharedTypes.cpp create mode 100644 src/introspection/IntrospectionSharedTypes.cpp diff --git a/cmake/cppgraphqlgen-update-schema-files.cmake b/cmake/cppgraphqlgen-update-schema-files.cmake index 5ca5c55e..44a840c2 100644 --- a/cmake/cppgraphqlgen-update-schema-files.cmake +++ b/cmake/cppgraphqlgen-update-schema-files.cmake @@ -54,7 +54,8 @@ foreach(OLD_FILE ${OLD_FILES}) NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.ixx" AND NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.cpp" AND NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}SharedTypes.h" AND - NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}SharedTypes.ixx") + NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}SharedTypes.ixx" AND + NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}SharedTypes.cpp") message(WARNING "Unexpected file in ${SCHEMA_TARGET} GraphQL schema sources: ${OLD_FILE}") endif() endif() diff --git a/include/SchemaGenerator.h b/include/SchemaGenerator.h index 8a7b54bb..561dc01c 100644 --- a/include/SchemaGenerator.h +++ b/include/SchemaGenerator.h @@ -40,9 +40,10 @@ class [[nodiscard("unnecessary construction")]] Generator [[nodiscard("unnecessary memory copy")]] std::string getSourceDir() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSchemaHeaderPath() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSchemaModulePath() const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getSchemaSourcePath() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSharedTypesHeaderPath() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSharedTypesModulePath() const noexcept; - [[nodiscard("unnecessary memory copy")]] std::string getSourcePath() const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getSharedTypesSourcePath() const noexcept; [[nodiscard("unnecessary call")]] bool outputSchemaHeader() const noexcept; [[nodiscard("unnecessary call")]] bool outputSchemaModule() const noexcept; @@ -62,7 +63,8 @@ class [[nodiscard("unnecessary construction")]] Generator [[nodiscard("unnecessary memory copy")]] std::string getResolverDeclaration( const OutputField& outputField) const noexcept; - [[nodiscard("unnecessary call")]] bool outputSource() const noexcept; + [[nodiscard("unnecessary call")]] bool outputSchemaSource() const noexcept; + [[nodiscard("unnecessary call")]] bool outputSharedTypesSource() const noexcept; void outputInterfaceImplementation(std::ostream& sourceFile, std::string_view cppType) const; void outputInterfaceIntrospection( std::ostream& sourceFile, const InterfaceType& interfaceType) const; @@ -100,9 +102,10 @@ class [[nodiscard("unnecessary construction")]] Generator const std::string _sourceDir; const std::string _schemaHeaderPath; const std::string _schemaModulePath; + const std::string _schemaSourcePath; const std::string _sharedTypesHeaderPath; const std::string _sharedTypesModulePath; - const std::string _sourcePath; + const std::string _sharedTypesSourcePath; }; } // namespace graphql::generator::schema diff --git a/samples/learn/schema/StarWarsSchema.cpp b/samples/learn/schema/StarWarsSchema.cpp index 90d252e1..3813cab7 100644 --- a/samples/learn/schema/StarWarsSchema.cpp +++ b/samples/learn/schema/StarWarsSchema.cpp @@ -22,129 +22,7 @@ using namespace std::literals; -namespace graphql { -namespace service { - -static const auto s_namesEpisode = learn::getEpisodeNames(); -static const auto s_valuesEpisode = learn::getEpisodeValues(); - -template <> -learn::Episode Argument::convert(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid Episode value)ex" } }; - } - - const auto result = internal::sorted_map_lookup( - s_valuesEpisode, - std::string_view { value.get() }); - - if (!result) - { - throw service::schema_exception { { R"ex(not a valid Episode value)ex" } }; - } - - return *result; -} - -template <> -service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) -{ - return ModifiedResult::resolve(std::move(result), std::move(params), - [](learn::Episode value, const ResolverParams&) - { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesEpisode[static_cast(value)] }); - - return resolvedResult; - }); -} - -template <> -void Result::validateScalar(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid Episode value)ex" } }; - } - - const auto [itr, itrEnd] = internal::sorted_map_equal_range( - s_valuesEpisode.begin(), - s_valuesEpisode.end(), - std::string_view { value.get() }); - - if (itr == itrEnd) - { - throw service::schema_exception { { R"ex(not a valid Episode value)ex" } }; - } -} - -template <> -learn::ReviewInput Argument::convert(const response::Value& value) -{ - auto valueStars = service::ModifiedArgument::require("stars", value); - auto valueCommentary = service::ModifiedArgument::require("commentary", value); - - return learn::ReviewInput { - valueStars, - std::move(valueCommentary) - }; -} - -} // namespace service - -namespace learn { - -ReviewInput::ReviewInput() noexcept - : stars {} - , commentary {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ReviewInput::ReviewInput( - int starsArg, - std::optional commentaryArg) noexcept - : stars { std::move(starsArg) } - , commentary { std::move(commentaryArg) } -{ -} - -ReviewInput::ReviewInput(const ReviewInput& other) - : stars { service::ModifiedArgument::duplicate(other.stars) } - , commentary { service::ModifiedArgument::duplicate(other.commentary) } -{ -} - -ReviewInput::ReviewInput(ReviewInput&& other) noexcept - : stars { std::move(other.stars) } - , commentary { std::move(other.commentary) } -{ -} - -ReviewInput::~ReviewInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ReviewInput& ReviewInput::operator=(const ReviewInput& other) -{ - ReviewInput value { other }; - - std::swap(*this, value); - - return *this; -} - -ReviewInput& ReviewInput::operator=(ReviewInput&& other) noexcept -{ - stars = std::move(other.stars); - commentary = std::move(other.commentary); - - return *this; -} +namespace graphql::learn { Operations::Operations(std::shared_ptr query, std::shared_ptr mutation, std::shared_ptr subscription) : service::Request({ @@ -179,10 +57,12 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeSubscription = schema::ObjectType::Make(R"gql(Subscription)gql"sv, R"md()md"sv); schema->AddType(R"gql(Subscription)gql"sv, typeSubscription); + + static const auto s_namesEpisode = getEpisodeNames(); typeEpisode->AddEnumValues({ - { service::s_namesEpisode[static_cast(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt }, - { service::s_namesEpisode[static_cast(learn::Episode::EMPIRE)], R"md()md"sv, std::nullopt }, - { service::s_namesEpisode[static_cast(learn::Episode::JEDI)], R"md()md"sv, std::nullopt } + { s_namesEpisode[static_cast(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt }, + { s_namesEpisode[static_cast(learn::Episode::EMPIRE)], R"md()md"sv, std::nullopt }, + { s_namesEpisode[static_cast(learn::Episode::JEDI)], R"md()md"sv, std::nullopt } }); typeReviewInput->AddInputValues({ @@ -220,5 +100,4 @@ std::shared_ptr GetSchema() return schema; } -} // namespace learn -} // namespace graphql +} // namespace graphql::learn diff --git a/samples/learn/schema/StarWarsSharedTypes.cpp b/samples/learn/schema/StarWarsSharedTypes.cpp new file mode 100644 index 00000000..3bfcae45 --- /dev/null +++ b/samples/learn/schema/StarWarsSharedTypes.cpp @@ -0,0 +1,146 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#include "graphqlservice/GraphQLService.h" + +#include "StarWarsSharedTypes.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace graphql { +namespace service { + +static const auto s_namesEpisode = learn::getEpisodeNames(); +static const auto s_valuesEpisode = learn::getEpisodeValues(); + +template <> +learn::Episode Argument::convert(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid Episode value)ex" } }; + } + + const auto result = internal::sorted_map_lookup( + s_valuesEpisode, + std::string_view { value.get() }); + + if (!result) + { + throw service::schema_exception { { R"ex(not a valid Episode value)ex" } }; + } + + return *result; +} + +template <> +service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), std::move(params), + [](learn::Episode value, const ResolverParams&) + { + response::Value resolvedResult(response::Type::EnumValue); + + resolvedResult.set(std::string { s_namesEpisode[static_cast(value)] }); + + return resolvedResult; + }); +} + +template <> +void Result::validateScalar(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid Episode value)ex" } }; + } + + const auto [itr, itrEnd] = internal::sorted_map_equal_range( + s_valuesEpisode.begin(), + s_valuesEpisode.end(), + std::string_view { value.get() }); + + if (itr == itrEnd) + { + throw service::schema_exception { { R"ex(not a valid Episode value)ex" } }; + } +} + +template <> +learn::ReviewInput Argument::convert(const response::Value& value) +{ + auto valueStars = service::ModifiedArgument::require("stars", value); + auto valueCommentary = service::ModifiedArgument::require("commentary", value); + + return learn::ReviewInput { + valueStars, + std::move(valueCommentary) + }; +} + +} // namespace service + +namespace learn { + +ReviewInput::ReviewInput() noexcept + : stars {} + , commentary {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ReviewInput::ReviewInput( + int starsArg, + std::optional commentaryArg) noexcept + : stars { std::move(starsArg) } + , commentary { std::move(commentaryArg) } +{ +} + +ReviewInput::ReviewInput(const ReviewInput& other) + : stars { service::ModifiedArgument::duplicate(other.stars) } + , commentary { service::ModifiedArgument::duplicate(other.commentary) } +{ +} + +ReviewInput::ReviewInput(ReviewInput&& other) noexcept + : stars { std::move(other.stars) } + , commentary { std::move(other.commentary) } +{ +} + +ReviewInput::~ReviewInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ReviewInput& ReviewInput::operator=(const ReviewInput& other) +{ + ReviewInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ReviewInput& ReviewInput::operator=(ReviewInput&& other) noexcept +{ + stars = std::move(other.stars); + commentary = std::move(other.commentary); + + return *this; +} + +} // namespace learn +} // namespace graphql diff --git a/samples/learn/schema/learn_schema_files b/samples/learn/schema/learn_schema_files index 3b3fc41b..4f26ca5c 100644 --- a/samples/learn/schema/learn_schema_files +++ b/samples/learn/schema/learn_schema_files @@ -1,3 +1,4 @@ +StarWarsSharedTypes.cpp StarWarsSchema.cpp CharacterObject.cpp HumanObject.cpp diff --git a/samples/proxy/schema/ProxySchema.cpp b/samples/proxy/schema/ProxySchema.cpp index 5f2c26b4..6be2146e 100644 --- a/samples/proxy/schema/ProxySchema.cpp +++ b/samples/proxy/schema/ProxySchema.cpp @@ -20,145 +20,7 @@ using namespace std::literals; -namespace graphql { -namespace service { - -static const auto s_namesOperationType = proxy::getOperationTypeNames(); -static const auto s_valuesOperationType = proxy::getOperationTypeValues(); - -template <> -proxy::OperationType Argument::convert(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; - } - - const auto result = internal::sorted_map_lookup( - s_valuesOperationType, - std::string_view { value.get() }); - - if (!result) - { - throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; - } - - return *result; -} - -template <> -service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) -{ - return ModifiedResult::resolve(std::move(result), std::move(params), - [](proxy::OperationType value, const ResolverParams&) - { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesOperationType[static_cast(value)] }); - - return resolvedResult; - }); -} - -template <> -void Result::validateScalar(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; - } - - const auto [itr, itrEnd] = internal::sorted_map_equal_range( - s_valuesOperationType.begin(), - s_valuesOperationType.end(), - std::string_view { value.get() }); - - if (itr == itrEnd) - { - throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; - } -} - -template <> -proxy::QueryInput Argument::convert(const response::Value& value) -{ - auto valueType = service::ModifiedArgument::require("type", value); - auto valueQuery = service::ModifiedArgument::require("query", value); - auto valueOperationName = service::ModifiedArgument::require("operationName", value); - auto valueVariables = service::ModifiedArgument::require("variables", value); - - return proxy::QueryInput { - std::move(valueType), - std::move(valueQuery), - std::move(valueOperationName), - std::move(valueVariables) - }; -} - -} // namespace service - -namespace proxy { - -QueryInput::QueryInput() noexcept - : type {} - , query {} - , operationName {} - , variables {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -QueryInput::QueryInput( - OperationType typeArg, - std::string queryArg, - std::optional operationNameArg, - std::optional variablesArg) noexcept - : type { std::move(typeArg) } - , query { std::move(queryArg) } - , operationName { std::move(operationNameArg) } - , variables { std::move(variablesArg) } -{ -} - -QueryInput::QueryInput(const QueryInput& other) - : type { service::ModifiedArgument::duplicate(other.type) } - , query { service::ModifiedArgument::duplicate(other.query) } - , operationName { service::ModifiedArgument::duplicate(other.operationName) } - , variables { service::ModifiedArgument::duplicate(other.variables) } -{ -} - -QueryInput::QueryInput(QueryInput&& other) noexcept - : type { std::move(other.type) } - , query { std::move(other.query) } - , operationName { std::move(other.operationName) } - , variables { std::move(other.variables) } -{ -} - -QueryInput::~QueryInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -QueryInput& QueryInput::operator=(const QueryInput& other) -{ - QueryInput value { other }; - - std::swap(*this, value); - - return *this; -} - -QueryInput& QueryInput::operator=(QueryInput&& other) noexcept -{ - type = std::move(other.type); - query = std::move(other.query); - operationName = std::move(other.operationName); - variables = std::move(other.variables); - - return *this; -} +namespace graphql::proxy { Operations::Operations(std::shared_ptr query) : service::Request({ @@ -179,10 +41,12 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeQueryResults = schema::ObjectType::Make(R"gql(QueryResults)gql"sv, R"md()md"sv); schema->AddType(R"gql(QueryResults)gql"sv, typeQueryResults); + + static const auto s_namesOperationType = getOperationTypeNames(); typeOperationType->AddEnumValues({ - { service::s_namesOperationType[static_cast(proxy::OperationType::QUERY)], R"md()md"sv, std::nullopt }, - { service::s_namesOperationType[static_cast(proxy::OperationType::MUTATION)], R"md()md"sv, std::nullopt }, - { service::s_namesOperationType[static_cast(proxy::OperationType::SUBSCRIPTION)], R"md()md"sv, std::nullopt } + { s_namesOperationType[static_cast(proxy::OperationType::QUERY)], R"md()md"sv, std::nullopt }, + { s_namesOperationType[static_cast(proxy::OperationType::MUTATION)], R"md()md"sv, std::nullopt }, + { s_namesOperationType[static_cast(proxy::OperationType::SUBSCRIPTION)], R"md()md"sv, std::nullopt } }); typeQueryInput->AddInputValues({ @@ -214,5 +78,4 @@ std::shared_ptr GetSchema() return schema; } -} // namespace proxy -} // namespace graphql +} // namespace graphql::proxy diff --git a/samples/proxy/schema/ProxySharedTypes.cpp b/samples/proxy/schema/ProxySharedTypes.cpp new file mode 100644 index 00000000..66aafa00 --- /dev/null +++ b/samples/proxy/schema/ProxySharedTypes.cpp @@ -0,0 +1,162 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#include "graphqlservice/GraphQLService.h" + +#include "ProxySharedTypes.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace graphql { +namespace service { + +static const auto s_namesOperationType = proxy::getOperationTypeNames(); +static const auto s_valuesOperationType = proxy::getOperationTypeValues(); + +template <> +proxy::OperationType Argument::convert(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; + } + + const auto result = internal::sorted_map_lookup( + s_valuesOperationType, + std::string_view { value.get() }); + + if (!result) + { + throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; + } + + return *result; +} + +template <> +service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), std::move(params), + [](proxy::OperationType value, const ResolverParams&) + { + response::Value resolvedResult(response::Type::EnumValue); + + resolvedResult.set(std::string { s_namesOperationType[static_cast(value)] }); + + return resolvedResult; + }); +} + +template <> +void Result::validateScalar(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; + } + + const auto [itr, itrEnd] = internal::sorted_map_equal_range( + s_valuesOperationType.begin(), + s_valuesOperationType.end(), + std::string_view { value.get() }); + + if (itr == itrEnd) + { + throw service::schema_exception { { R"ex(not a valid OperationType value)ex" } }; + } +} + +template <> +proxy::QueryInput Argument::convert(const response::Value& value) +{ + auto valueType = service::ModifiedArgument::require("type", value); + auto valueQuery = service::ModifiedArgument::require("query", value); + auto valueOperationName = service::ModifiedArgument::require("operationName", value); + auto valueVariables = service::ModifiedArgument::require("variables", value); + + return proxy::QueryInput { + std::move(valueType), + std::move(valueQuery), + std::move(valueOperationName), + std::move(valueVariables) + }; +} + +} // namespace service + +namespace proxy { + +QueryInput::QueryInput() noexcept + : type {} + , query {} + , operationName {} + , variables {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +QueryInput::QueryInput( + OperationType typeArg, + std::string queryArg, + std::optional operationNameArg, + std::optional variablesArg) noexcept + : type { std::move(typeArg) } + , query { std::move(queryArg) } + , operationName { std::move(operationNameArg) } + , variables { std::move(variablesArg) } +{ +} + +QueryInput::QueryInput(const QueryInput& other) + : type { service::ModifiedArgument::duplicate(other.type) } + , query { service::ModifiedArgument::duplicate(other.query) } + , operationName { service::ModifiedArgument::duplicate(other.operationName) } + , variables { service::ModifiedArgument::duplicate(other.variables) } +{ +} + +QueryInput::QueryInput(QueryInput&& other) noexcept + : type { std::move(other.type) } + , query { std::move(other.query) } + , operationName { std::move(other.operationName) } + , variables { std::move(other.variables) } +{ +} + +QueryInput::~QueryInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +QueryInput& QueryInput::operator=(const QueryInput& other) +{ + QueryInput value { other }; + + std::swap(*this, value); + + return *this; +} + +QueryInput& QueryInput::operator=(QueryInput&& other) noexcept +{ + type = std::move(other.type); + query = std::move(other.query); + operationName = std::move(other.operationName); + variables = std::move(other.variables); + + return *this; +} + +} // namespace proxy +} // namespace graphql diff --git a/samples/proxy/schema/proxy_schema_files b/samples/proxy/schema/proxy_schema_files index 3b54c3a5..abca35d2 100644 --- a/samples/proxy/schema/proxy_schema_files +++ b/samples/proxy/schema/proxy_schema_files @@ -1,3 +1,4 @@ +ProxySharedTypes.cpp ProxySchema.cpp QueryObject.cpp QueryResultsObject.cpp diff --git a/samples/today/nointrospection/TodaySchema.cpp b/samples/today/nointrospection/TodaySchema.cpp index cb72d659..106258d5 100644 --- a/samples/today/nointrospection/TodaySchema.cpp +++ b/samples/today/nointrospection/TodaySchema.cpp @@ -22,711 +22,7 @@ using namespace std::literals; -namespace graphql { -namespace service { - -static const auto s_namesTaskState = today::getTaskStateNames(); -static const auto s_valuesTaskState = today::getTaskStateValues(); - -template <> -today::TaskState Argument::convert(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; - } - - const auto result = internal::sorted_map_lookup( - s_valuesTaskState, - std::string_view { value.get() }); - - if (!result) - { - throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; - } - - return *result; -} - -template <> -service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) -{ - return ModifiedResult::resolve(std::move(result), std::move(params), - [](today::TaskState value, const ResolverParams&) - { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); - - return resolvedResult; - }); -} - -template <> -void Result::validateScalar(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; - } - - const auto [itr, itrEnd] = internal::sorted_map_equal_range( - s_valuesTaskState.begin(), - s_valuesTaskState.end(), - std::string_view { value.get() }); - - if (itr == itrEnd) - { - throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; - } -} - -template <> -today::CompleteTaskInput Argument::convert(const response::Value& value) -{ - const auto defaultValue = []() - { - response::Value values(response::Type::Map); - response::Value entry; - - entry = response::Value(true); - values.emplace_back("isComplete", std::move(entry)); - - return values; - }(); - - auto valueId = service::ModifiedArgument::require("id", value); - auto valueTestTaskState = service::ModifiedArgument::require("testTaskState", value); - auto pairIsComplete = service::ModifiedArgument::find("isComplete", value); - auto valueIsComplete = (pairIsComplete.second - ? std::move(pairIsComplete.first) - : service::ModifiedArgument::require("isComplete", defaultValue)); - auto valueClientMutationId = service::ModifiedArgument::require("clientMutationId", value); - - return today::CompleteTaskInput { - std::move(valueId), - valueTestTaskState, - std::move(valueIsComplete), - std::move(valueClientMutationId) - }; -} - -template <> -today::ThirdNestedInput Argument::convert(const response::Value& value) -{ - auto valueId = service::ModifiedArgument::require("id", value); - auto valueSecond = service::ModifiedArgument::require("second", value); - - return today::ThirdNestedInput { - std::move(valueId), - std::move(valueSecond) - }; -} - -template <> -today::FourthNestedInput Argument::convert(const response::Value& value) -{ - auto valueId = service::ModifiedArgument::require("id", value); - - return today::FourthNestedInput { - std::move(valueId) - }; -} - -template <> -today::IncludeNullableSelfInput Argument::convert(const response::Value& value) -{ - auto valueSelf = service::ModifiedArgument::require("self", value); - - return today::IncludeNullableSelfInput { - std::move(valueSelf) - }; -} - -template <> -today::IncludeNonNullableListSelfInput Argument::convert(const response::Value& value) -{ - auto valueSelves = service::ModifiedArgument::require("selves", value); - - return today::IncludeNonNullableListSelfInput { - std::move(valueSelves) - }; -} - -template <> -today::StringOperationFilterInput Argument::convert(const response::Value& value) -{ - auto valueAnd_ = service::ModifiedArgument::require("and", value); - auto valueOr_ = service::ModifiedArgument::require("or", value); - auto valueEqual = service::ModifiedArgument::require("equal", value); - auto valueNotEqual = service::ModifiedArgument::require("notEqual", value); - auto valueContains = service::ModifiedArgument::require("contains", value); - auto valueNotContains = service::ModifiedArgument::require("notContains", value); - auto valueIn = service::ModifiedArgument::require("in", value); - auto valueNotIn = service::ModifiedArgument::require("notIn", value); - auto valueStartsWith = service::ModifiedArgument::require("startsWith", value); - auto valueNotStartsWith = service::ModifiedArgument::require("notStartsWith", value); - auto valueEndsWith = service::ModifiedArgument::require("endsWith", value); - auto valueNotEndsWith = service::ModifiedArgument::require("notEndsWith", value); - - return today::StringOperationFilterInput { - std::move(valueAnd_), - std::move(valueOr_), - std::move(valueEqual), - std::move(valueNotEqual), - std::move(valueContains), - std::move(valueNotContains), - std::move(valueIn), - std::move(valueNotIn), - std::move(valueStartsWith), - std::move(valueNotStartsWith), - std::move(valueEndsWith), - std::move(valueNotEndsWith) - }; -} - -template <> -today::SecondNestedInput Argument::convert(const response::Value& value) -{ - auto valueId = service::ModifiedArgument::require("id", value); - auto valueThird = service::ModifiedArgument::require("third", value); - - return today::SecondNestedInput { - std::move(valueId), - std::move(valueThird) - }; -} - -template <> -today::ForwardDeclaredInput Argument::convert(const response::Value& value) -{ - auto valueNullableSelf = service::ModifiedArgument::require("nullableSelf", value); - auto valueListSelves = service::ModifiedArgument::require("listSelves", value); - - return today::ForwardDeclaredInput { - std::move(valueNullableSelf), - std::move(valueListSelves) - }; -} - -template <> -today::FirstNestedInput Argument::convert(const response::Value& value) -{ - auto valueId = service::ModifiedArgument::require("id", value); - auto valueSecond = service::ModifiedArgument::require("second", value); - auto valueThird = service::ModifiedArgument::require("third", value); - - return today::FirstNestedInput { - std::move(valueId), - std::move(valueSecond), - std::move(valueThird) - }; -} - -} // namespace service - -namespace today { - -CompleteTaskInput::CompleteTaskInput() noexcept - : id {} - , testTaskState {} - , isComplete {} - , clientMutationId {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -CompleteTaskInput::CompleteTaskInput( - response::IdType idArg, - std::optional testTaskStateArg, - std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept - : id { std::move(idArg) } - , testTaskState { std::move(testTaskStateArg) } - , isComplete { std::move(isCompleteArg) } - , clientMutationId { std::move(clientMutationIdArg) } -{ -} - -CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) - : id { service::ModifiedArgument::duplicate(other.id) } - , testTaskState { service::ModifiedArgument::duplicate(other.testTaskState) } - , isComplete { service::ModifiedArgument::duplicate(other.isComplete) } - , clientMutationId { service::ModifiedArgument::duplicate(other.clientMutationId) } -{ -} - -CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept - : id { std::move(other.id) } - , testTaskState { std::move(other.testTaskState) } - , isComplete { std::move(other.isComplete) } - , clientMutationId { std::move(other.clientMutationId) } -{ -} - -CompleteTaskInput::~CompleteTaskInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -CompleteTaskInput& CompleteTaskInput::operator=(const CompleteTaskInput& other) -{ - CompleteTaskInput value { other }; - - std::swap(*this, value); - - return *this; -} - -CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexcept -{ - id = std::move(other.id); - testTaskState = std::move(other.testTaskState); - isComplete = std::move(other.isComplete); - clientMutationId = std::move(other.clientMutationId); - - return *this; -} - -ThirdNestedInput::ThirdNestedInput() noexcept - : id {} - , second {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ThirdNestedInput::ThirdNestedInput( - response::IdType idArg, - std::unique_ptr secondArg) noexcept - : id { std::move(idArg) } - , second { std::move(secondArg) } -{ -} - -ThirdNestedInput::ThirdNestedInput(const ThirdNestedInput& other) - : id { service::ModifiedArgument::duplicate(other.id) } - , second { service::ModifiedArgument::duplicate(other.second) } -{ -} - -ThirdNestedInput::ThirdNestedInput(ThirdNestedInput&& other) noexcept - : id { std::move(other.id) } - , second { std::move(other.second) } -{ -} - -ThirdNestedInput::~ThirdNestedInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ThirdNestedInput& ThirdNestedInput::operator=(const ThirdNestedInput& other) -{ - ThirdNestedInput value { other }; - - std::swap(*this, value); - - return *this; -} - -ThirdNestedInput& ThirdNestedInput::operator=(ThirdNestedInput&& other) noexcept -{ - id = std::move(other.id); - second = std::move(other.second); - - return *this; -} - -FourthNestedInput::FourthNestedInput() noexcept - : id {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -FourthNestedInput::FourthNestedInput( - response::IdType idArg) noexcept - : id { std::move(idArg) } -{ -} - -FourthNestedInput::FourthNestedInput(const FourthNestedInput& other) - : id { service::ModifiedArgument::duplicate(other.id) } -{ -} - -FourthNestedInput::FourthNestedInput(FourthNestedInput&& other) noexcept - : id { std::move(other.id) } -{ -} - -FourthNestedInput::~FourthNestedInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -FourthNestedInput& FourthNestedInput::operator=(const FourthNestedInput& other) -{ - FourthNestedInput value { other }; - - std::swap(*this, value); - - return *this; -} - -FourthNestedInput& FourthNestedInput::operator=(FourthNestedInput&& other) noexcept -{ - id = std::move(other.id); - - return *this; -} - -IncludeNullableSelfInput::IncludeNullableSelfInput() noexcept - : self {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -IncludeNullableSelfInput::IncludeNullableSelfInput( - std::unique_ptr selfArg) noexcept - : self { std::move(selfArg) } -{ -} - -IncludeNullableSelfInput::IncludeNullableSelfInput(const IncludeNullableSelfInput& other) - : self { service::ModifiedArgument::duplicate(other.self) } -{ -} - -IncludeNullableSelfInput::IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept - : self { std::move(other.self) } -{ -} - -IncludeNullableSelfInput::~IncludeNullableSelfInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(const IncludeNullableSelfInput& other) -{ - IncludeNullableSelfInput value { other }; - - std::swap(*this, value); - - return *this; -} - -IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(IncludeNullableSelfInput&& other) noexcept -{ - self = std::move(other.self); - - return *this; -} - -IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput() noexcept - : selves {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput( - std::vector selvesArg) noexcept - : selves { std::move(selvesArg) } -{ -} - -IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other) - : selves { service::ModifiedArgument::duplicate(other.selves) } -{ -} - -IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept - : selves { std::move(other.selves) } -{ -} - -IncludeNonNullableListSelfInput::~IncludeNonNullableListSelfInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(const IncludeNonNullableListSelfInput& other) -{ - IncludeNonNullableListSelfInput value { other }; - - std::swap(*this, value); - - return *this; -} - -IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(IncludeNonNullableListSelfInput&& other) noexcept -{ - selves = std::move(other.selves); - - return *this; -} - -StringOperationFilterInput::StringOperationFilterInput() noexcept - : and_ {} - , or_ {} - , equal {} - , notEqual {} - , contains {} - , notContains {} - , in {} - , notIn {} - , startsWith {} - , notStartsWith {} - , endsWith {} - , notEndsWith {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -StringOperationFilterInput::StringOperationFilterInput( - std::optional> and_Arg, - std::optional> or_Arg, - std::optional equalArg, - std::optional notEqualArg, - std::optional containsArg, - std::optional notContainsArg, - std::optional> inArg, - std::optional> notInArg, - std::optional startsWithArg, - std::optional notStartsWithArg, - std::optional endsWithArg, - std::optional notEndsWithArg) noexcept - : and_ { std::move(and_Arg) } - , or_ { std::move(or_Arg) } - , equal { std::move(equalArg) } - , notEqual { std::move(notEqualArg) } - , contains { std::move(containsArg) } - , notContains { std::move(notContainsArg) } - , in { std::move(inArg) } - , notIn { std::move(notInArg) } - , startsWith { std::move(startsWithArg) } - , notStartsWith { std::move(notStartsWithArg) } - , endsWith { std::move(endsWithArg) } - , notEndsWith { std::move(notEndsWithArg) } -{ -} - -StringOperationFilterInput::StringOperationFilterInput(const StringOperationFilterInput& other) - : and_ { service::ModifiedArgument::duplicate(other.and_) } - , or_ { service::ModifiedArgument::duplicate(other.or_) } - , equal { service::ModifiedArgument::duplicate(other.equal) } - , notEqual { service::ModifiedArgument::duplicate(other.notEqual) } - , contains { service::ModifiedArgument::duplicate(other.contains) } - , notContains { service::ModifiedArgument::duplicate(other.notContains) } - , in { service::ModifiedArgument::duplicate(other.in) } - , notIn { service::ModifiedArgument::duplicate(other.notIn) } - , startsWith { service::ModifiedArgument::duplicate(other.startsWith) } - , notStartsWith { service::ModifiedArgument::duplicate(other.notStartsWith) } - , endsWith { service::ModifiedArgument::duplicate(other.endsWith) } - , notEndsWith { service::ModifiedArgument::duplicate(other.notEndsWith) } -{ -} - -StringOperationFilterInput::StringOperationFilterInput(StringOperationFilterInput&& other) noexcept - : and_ { std::move(other.and_) } - , or_ { std::move(other.or_) } - , equal { std::move(other.equal) } - , notEqual { std::move(other.notEqual) } - , contains { std::move(other.contains) } - , notContains { std::move(other.notContains) } - , in { std::move(other.in) } - , notIn { std::move(other.notIn) } - , startsWith { std::move(other.startsWith) } - , notStartsWith { std::move(other.notStartsWith) } - , endsWith { std::move(other.endsWith) } - , notEndsWith { std::move(other.notEndsWith) } -{ -} - -StringOperationFilterInput::~StringOperationFilterInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -StringOperationFilterInput& StringOperationFilterInput::operator=(const StringOperationFilterInput& other) -{ - StringOperationFilterInput value { other }; - - std::swap(*this, value); - - return *this; -} - -StringOperationFilterInput& StringOperationFilterInput::operator=(StringOperationFilterInput&& other) noexcept -{ - and_ = std::move(other.and_); - or_ = std::move(other.or_); - equal = std::move(other.equal); - notEqual = std::move(other.notEqual); - contains = std::move(other.contains); - notContains = std::move(other.notContains); - in = std::move(other.in); - notIn = std::move(other.notIn); - startsWith = std::move(other.startsWith); - notStartsWith = std::move(other.notStartsWith); - endsWith = std::move(other.endsWith); - notEndsWith = std::move(other.notEndsWith); - - return *this; -} - -SecondNestedInput::SecondNestedInput() noexcept - : id {} - , third {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -SecondNestedInput::SecondNestedInput( - response::IdType idArg, - ThirdNestedInput thirdArg) noexcept - : id { std::move(idArg) } - , third { std::move(thirdArg) } -{ -} - -SecondNestedInput::SecondNestedInput(const SecondNestedInput& other) - : id { service::ModifiedArgument::duplicate(other.id) } - , third { service::ModifiedArgument::duplicate(other.third) } -{ -} - -SecondNestedInput::SecondNestedInput(SecondNestedInput&& other) noexcept - : id { std::move(other.id) } - , third { std::move(other.third) } -{ -} - -SecondNestedInput::~SecondNestedInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -SecondNestedInput& SecondNestedInput::operator=(const SecondNestedInput& other) -{ - SecondNestedInput value { other }; - - std::swap(*this, value); - - return *this; -} - -SecondNestedInput& SecondNestedInput::operator=(SecondNestedInput&& other) noexcept -{ - id = std::move(other.id); - third = std::move(other.third); - - return *this; -} - -ForwardDeclaredInput::ForwardDeclaredInput() noexcept - : nullableSelf {} - , listSelves {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ForwardDeclaredInput::ForwardDeclaredInput( - std::unique_ptr nullableSelfArg, - IncludeNonNullableListSelfInput listSelvesArg) noexcept - : nullableSelf { std::move(nullableSelfArg) } - , listSelves { std::move(listSelvesArg) } -{ -} - -ForwardDeclaredInput::ForwardDeclaredInput(const ForwardDeclaredInput& other) - : nullableSelf { service::ModifiedArgument::duplicate(other.nullableSelf) } - , listSelves { service::ModifiedArgument::duplicate(other.listSelves) } -{ -} - -ForwardDeclaredInput::ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept - : nullableSelf { std::move(other.nullableSelf) } - , listSelves { std::move(other.listSelves) } -{ -} - -ForwardDeclaredInput::~ForwardDeclaredInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ForwardDeclaredInput& ForwardDeclaredInput::operator=(const ForwardDeclaredInput& other) -{ - ForwardDeclaredInput value { other }; - - std::swap(*this, value); - - return *this; -} - -ForwardDeclaredInput& ForwardDeclaredInput::operator=(ForwardDeclaredInput&& other) noexcept -{ - nullableSelf = std::move(other.nullableSelf); - listSelves = std::move(other.listSelves); - - return *this; -} - -FirstNestedInput::FirstNestedInput() noexcept - : id {} - , second {} - , third {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -FirstNestedInput::FirstNestedInput( - response::IdType idArg, - SecondNestedInput secondArg, - ThirdNestedInput thirdArg) noexcept - : id { std::move(idArg) } - , second { std::move(secondArg) } - , third { std::move(thirdArg) } -{ -} - -FirstNestedInput::FirstNestedInput(const FirstNestedInput& other) - : id { service::ModifiedArgument::duplicate(other.id) } - , second { service::ModifiedArgument::duplicate(other.second) } - , third { service::ModifiedArgument::duplicate(other.third) } -{ -} - -FirstNestedInput::FirstNestedInput(FirstNestedInput&& other) noexcept - : id { std::move(other.id) } - , second { std::move(other.second) } - , third { std::move(other.third) } -{ -} - -FirstNestedInput::~FirstNestedInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -FirstNestedInput& FirstNestedInput::operator=(const FirstNestedInput& other) -{ - FirstNestedInput value { other }; - - std::swap(*this, value); - - return *this; -} - -FirstNestedInput& FirstNestedInput::operator=(FirstNestedInput&& other) noexcept -{ - id = std::move(other.id); - second = std::move(other.second); - third = std::move(other.third); - - return *this; -} +namespace graphql::today { Operations::Operations(std::shared_ptr query, std::shared_ptr mutation, std::shared_ptr subscription) : service::Request({ @@ -801,11 +97,13 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeExpensive = schema::ObjectType::Make(R"gql(Expensive)gql"sv, R"md()md"sv); schema->AddType(R"gql(Expensive)gql"sv, typeExpensive); + + static const auto s_namesTaskState = getTaskStateNames(); typeTaskState->AddEnumValues({ - { service::s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, - { service::s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } + { s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, + { s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, + { s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, + { s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } }); typeCompleteTaskInput->AddInputValues({ @@ -929,5 +227,4 @@ std::shared_ptr GetSchema() return schema; } -} // namespace today -} // namespace graphql +} // namespace graphql::today diff --git a/samples/today/nointrospection/TodaySharedTypes.cpp b/samples/today/nointrospection/TodaySharedTypes.cpp new file mode 100644 index 00000000..d3a0c4a0 --- /dev/null +++ b/samples/today/nointrospection/TodaySharedTypes.cpp @@ -0,0 +1,736 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#include "graphqlservice/GraphQLService.h" + +#include "TodaySharedTypes.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace graphql { +namespace service { + +static const auto s_namesTaskState = today::getTaskStateNames(); +static const auto s_valuesTaskState = today::getTaskStateValues(); + +template <> +today::TaskState Argument::convert(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; + } + + const auto result = internal::sorted_map_lookup( + s_valuesTaskState, + std::string_view { value.get() }); + + if (!result) + { + throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; + } + + return *result; +} + +template <> +service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), std::move(params), + [](today::TaskState value, const ResolverParams&) + { + response::Value resolvedResult(response::Type::EnumValue); + + resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); + + return resolvedResult; + }); +} + +template <> +void Result::validateScalar(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; + } + + const auto [itr, itrEnd] = internal::sorted_map_equal_range( + s_valuesTaskState.begin(), + s_valuesTaskState.end(), + std::string_view { value.get() }); + + if (itr == itrEnd) + { + throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; + } +} + +template <> +today::CompleteTaskInput Argument::convert(const response::Value& value) +{ + const auto defaultValue = []() + { + response::Value values(response::Type::Map); + response::Value entry; + + entry = response::Value(true); + values.emplace_back("isComplete", std::move(entry)); + + return values; + }(); + + auto valueId = service::ModifiedArgument::require("id", value); + auto valueTestTaskState = service::ModifiedArgument::require("testTaskState", value); + auto pairIsComplete = service::ModifiedArgument::find("isComplete", value); + auto valueIsComplete = (pairIsComplete.second + ? std::move(pairIsComplete.first) + : service::ModifiedArgument::require("isComplete", defaultValue)); + auto valueClientMutationId = service::ModifiedArgument::require("clientMutationId", value); + + return today::CompleteTaskInput { + std::move(valueId), + valueTestTaskState, + std::move(valueIsComplete), + std::move(valueClientMutationId) + }; +} + +template <> +today::ThirdNestedInput Argument::convert(const response::Value& value) +{ + auto valueId = service::ModifiedArgument::require("id", value); + auto valueSecond = service::ModifiedArgument::require("second", value); + + return today::ThirdNestedInput { + std::move(valueId), + std::move(valueSecond) + }; +} + +template <> +today::FourthNestedInput Argument::convert(const response::Value& value) +{ + auto valueId = service::ModifiedArgument::require("id", value); + + return today::FourthNestedInput { + std::move(valueId) + }; +} + +template <> +today::IncludeNullableSelfInput Argument::convert(const response::Value& value) +{ + auto valueSelf = service::ModifiedArgument::require("self", value); + + return today::IncludeNullableSelfInput { + std::move(valueSelf) + }; +} + +template <> +today::IncludeNonNullableListSelfInput Argument::convert(const response::Value& value) +{ + auto valueSelves = service::ModifiedArgument::require("selves", value); + + return today::IncludeNonNullableListSelfInput { + std::move(valueSelves) + }; +} + +template <> +today::StringOperationFilterInput Argument::convert(const response::Value& value) +{ + auto valueAnd_ = service::ModifiedArgument::require("and", value); + auto valueOr_ = service::ModifiedArgument::require("or", value); + auto valueEqual = service::ModifiedArgument::require("equal", value); + auto valueNotEqual = service::ModifiedArgument::require("notEqual", value); + auto valueContains = service::ModifiedArgument::require("contains", value); + auto valueNotContains = service::ModifiedArgument::require("notContains", value); + auto valueIn = service::ModifiedArgument::require("in", value); + auto valueNotIn = service::ModifiedArgument::require("notIn", value); + auto valueStartsWith = service::ModifiedArgument::require("startsWith", value); + auto valueNotStartsWith = service::ModifiedArgument::require("notStartsWith", value); + auto valueEndsWith = service::ModifiedArgument::require("endsWith", value); + auto valueNotEndsWith = service::ModifiedArgument::require("notEndsWith", value); + + return today::StringOperationFilterInput { + std::move(valueAnd_), + std::move(valueOr_), + std::move(valueEqual), + std::move(valueNotEqual), + std::move(valueContains), + std::move(valueNotContains), + std::move(valueIn), + std::move(valueNotIn), + std::move(valueStartsWith), + std::move(valueNotStartsWith), + std::move(valueEndsWith), + std::move(valueNotEndsWith) + }; +} + +template <> +today::SecondNestedInput Argument::convert(const response::Value& value) +{ + auto valueId = service::ModifiedArgument::require("id", value); + auto valueThird = service::ModifiedArgument::require("third", value); + + return today::SecondNestedInput { + std::move(valueId), + std::move(valueThird) + }; +} + +template <> +today::ForwardDeclaredInput Argument::convert(const response::Value& value) +{ + auto valueNullableSelf = service::ModifiedArgument::require("nullableSelf", value); + auto valueListSelves = service::ModifiedArgument::require("listSelves", value); + + return today::ForwardDeclaredInput { + std::move(valueNullableSelf), + std::move(valueListSelves) + }; +} + +template <> +today::FirstNestedInput Argument::convert(const response::Value& value) +{ + auto valueId = service::ModifiedArgument::require("id", value); + auto valueSecond = service::ModifiedArgument::require("second", value); + auto valueThird = service::ModifiedArgument::require("third", value); + + return today::FirstNestedInput { + std::move(valueId), + std::move(valueSecond), + std::move(valueThird) + }; +} + +} // namespace service + +namespace today { + +CompleteTaskInput::CompleteTaskInput() noexcept + : id {} + , testTaskState {} + , isComplete {} + , clientMutationId {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +CompleteTaskInput::CompleteTaskInput( + response::IdType idArg, + std::optional testTaskStateArg, + std::optional isCompleteArg, + std::optional clientMutationIdArg) noexcept + : id { std::move(idArg) } + , testTaskState { std::move(testTaskStateArg) } + , isComplete { std::move(isCompleteArg) } + , clientMutationId { std::move(clientMutationIdArg) } +{ +} + +CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , testTaskState { service::ModifiedArgument::duplicate(other.testTaskState) } + , isComplete { service::ModifiedArgument::duplicate(other.isComplete) } + , clientMutationId { service::ModifiedArgument::duplicate(other.clientMutationId) } +{ +} + +CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept + : id { std::move(other.id) } + , testTaskState { std::move(other.testTaskState) } + , isComplete { std::move(other.isComplete) } + , clientMutationId { std::move(other.clientMutationId) } +{ +} + +CompleteTaskInput::~CompleteTaskInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +CompleteTaskInput& CompleteTaskInput::operator=(const CompleteTaskInput& other) +{ + CompleteTaskInput value { other }; + + std::swap(*this, value); + + return *this; +} + +CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexcept +{ + id = std::move(other.id); + testTaskState = std::move(other.testTaskState); + isComplete = std::move(other.isComplete); + clientMutationId = std::move(other.clientMutationId); + + return *this; +} + + +ThirdNestedInput::ThirdNestedInput() noexcept + : id {} + , second {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ThirdNestedInput::ThirdNestedInput( + response::IdType idArg, + std::unique_ptr secondArg) noexcept + : id { std::move(idArg) } + , second { std::move(secondArg) } +{ +} + +ThirdNestedInput::ThirdNestedInput(const ThirdNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , second { service::ModifiedArgument::duplicate(other.second) } +{ +} + +ThirdNestedInput::ThirdNestedInput(ThirdNestedInput&& other) noexcept + : id { std::move(other.id) } + , second { std::move(other.second) } +{ +} + +ThirdNestedInput::~ThirdNestedInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ThirdNestedInput& ThirdNestedInput::operator=(const ThirdNestedInput& other) +{ + ThirdNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ThirdNestedInput& ThirdNestedInput::operator=(ThirdNestedInput&& other) noexcept +{ + id = std::move(other.id); + second = std::move(other.second); + + return *this; +} + + +FourthNestedInput::FourthNestedInput() noexcept + : id {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +FourthNestedInput::FourthNestedInput( + response::IdType idArg) noexcept + : id { std::move(idArg) } +{ +} + +FourthNestedInput::FourthNestedInput(const FourthNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } +{ +} + +FourthNestedInput::FourthNestedInput(FourthNestedInput&& other) noexcept + : id { std::move(other.id) } +{ +} + +FourthNestedInput::~FourthNestedInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +FourthNestedInput& FourthNestedInput::operator=(const FourthNestedInput& other) +{ + FourthNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +FourthNestedInput& FourthNestedInput::operator=(FourthNestedInput&& other) noexcept +{ + id = std::move(other.id); + + return *this; +} + + +IncludeNullableSelfInput::IncludeNullableSelfInput() noexcept + : self {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +IncludeNullableSelfInput::IncludeNullableSelfInput( + std::unique_ptr selfArg) noexcept + : self { std::move(selfArg) } +{ +} + +IncludeNullableSelfInput::IncludeNullableSelfInput(const IncludeNullableSelfInput& other) + : self { service::ModifiedArgument::duplicate(other.self) } +{ +} + +IncludeNullableSelfInput::IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept + : self { std::move(other.self) } +{ +} + +IncludeNullableSelfInput::~IncludeNullableSelfInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(const IncludeNullableSelfInput& other) +{ + IncludeNullableSelfInput value { other }; + + std::swap(*this, value); + + return *this; +} + +IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(IncludeNullableSelfInput&& other) noexcept +{ + self = std::move(other.self); + + return *this; +} + + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput() noexcept + : selves {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput( + std::vector selvesArg) noexcept + : selves { std::move(selvesArg) } +{ +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other) + : selves { service::ModifiedArgument::duplicate(other.selves) } +{ +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept + : selves { std::move(other.selves) } +{ +} + +IncludeNonNullableListSelfInput::~IncludeNonNullableListSelfInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(const IncludeNonNullableListSelfInput& other) +{ + IncludeNonNullableListSelfInput value { other }; + + std::swap(*this, value); + + return *this; +} + +IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(IncludeNonNullableListSelfInput&& other) noexcept +{ + selves = std::move(other.selves); + + return *this; +} + + +StringOperationFilterInput::StringOperationFilterInput() noexcept + : and_ {} + , or_ {} + , equal {} + , notEqual {} + , contains {} + , notContains {} + , in {} + , notIn {} + , startsWith {} + , notStartsWith {} + , endsWith {} + , notEndsWith {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +StringOperationFilterInput::StringOperationFilterInput( + std::optional> and_Arg, + std::optional> or_Arg, + std::optional equalArg, + std::optional notEqualArg, + std::optional containsArg, + std::optional notContainsArg, + std::optional> inArg, + std::optional> notInArg, + std::optional startsWithArg, + std::optional notStartsWithArg, + std::optional endsWithArg, + std::optional notEndsWithArg) noexcept + : and_ { std::move(and_Arg) } + , or_ { std::move(or_Arg) } + , equal { std::move(equalArg) } + , notEqual { std::move(notEqualArg) } + , contains { std::move(containsArg) } + , notContains { std::move(notContainsArg) } + , in { std::move(inArg) } + , notIn { std::move(notInArg) } + , startsWith { std::move(startsWithArg) } + , notStartsWith { std::move(notStartsWithArg) } + , endsWith { std::move(endsWithArg) } + , notEndsWith { std::move(notEndsWithArg) } +{ +} + +StringOperationFilterInput::StringOperationFilterInput(const StringOperationFilterInput& other) + : and_ { service::ModifiedArgument::duplicate(other.and_) } + , or_ { service::ModifiedArgument::duplicate(other.or_) } + , equal { service::ModifiedArgument::duplicate(other.equal) } + , notEqual { service::ModifiedArgument::duplicate(other.notEqual) } + , contains { service::ModifiedArgument::duplicate(other.contains) } + , notContains { service::ModifiedArgument::duplicate(other.notContains) } + , in { service::ModifiedArgument::duplicate(other.in) } + , notIn { service::ModifiedArgument::duplicate(other.notIn) } + , startsWith { service::ModifiedArgument::duplicate(other.startsWith) } + , notStartsWith { service::ModifiedArgument::duplicate(other.notStartsWith) } + , endsWith { service::ModifiedArgument::duplicate(other.endsWith) } + , notEndsWith { service::ModifiedArgument::duplicate(other.notEndsWith) } +{ +} + +StringOperationFilterInput::StringOperationFilterInput(StringOperationFilterInput&& other) noexcept + : and_ { std::move(other.and_) } + , or_ { std::move(other.or_) } + , equal { std::move(other.equal) } + , notEqual { std::move(other.notEqual) } + , contains { std::move(other.contains) } + , notContains { std::move(other.notContains) } + , in { std::move(other.in) } + , notIn { std::move(other.notIn) } + , startsWith { std::move(other.startsWith) } + , notStartsWith { std::move(other.notStartsWith) } + , endsWith { std::move(other.endsWith) } + , notEndsWith { std::move(other.notEndsWith) } +{ +} + +StringOperationFilterInput::~StringOperationFilterInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +StringOperationFilterInput& StringOperationFilterInput::operator=(const StringOperationFilterInput& other) +{ + StringOperationFilterInput value { other }; + + std::swap(*this, value); + + return *this; +} + +StringOperationFilterInput& StringOperationFilterInput::operator=(StringOperationFilterInput&& other) noexcept +{ + and_ = std::move(other.and_); + or_ = std::move(other.or_); + equal = std::move(other.equal); + notEqual = std::move(other.notEqual); + contains = std::move(other.contains); + notContains = std::move(other.notContains); + in = std::move(other.in); + notIn = std::move(other.notIn); + startsWith = std::move(other.startsWith); + notStartsWith = std::move(other.notStartsWith); + endsWith = std::move(other.endsWith); + notEndsWith = std::move(other.notEndsWith); + + return *this; +} + + +SecondNestedInput::SecondNestedInput() noexcept + : id {} + , third {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +SecondNestedInput::SecondNestedInput( + response::IdType idArg, + ThirdNestedInput thirdArg) noexcept + : id { std::move(idArg) } + , third { std::move(thirdArg) } +{ +} + +SecondNestedInput::SecondNestedInput(const SecondNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , third { service::ModifiedArgument::duplicate(other.third) } +{ +} + +SecondNestedInput::SecondNestedInput(SecondNestedInput&& other) noexcept + : id { std::move(other.id) } + , third { std::move(other.third) } +{ +} + +SecondNestedInput::~SecondNestedInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +SecondNestedInput& SecondNestedInput::operator=(const SecondNestedInput& other) +{ + SecondNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +SecondNestedInput& SecondNestedInput::operator=(SecondNestedInput&& other) noexcept +{ + id = std::move(other.id); + third = std::move(other.third); + + return *this; +} + + +ForwardDeclaredInput::ForwardDeclaredInput() noexcept + : nullableSelf {} + , listSelves {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ForwardDeclaredInput::ForwardDeclaredInput( + std::unique_ptr nullableSelfArg, + IncludeNonNullableListSelfInput listSelvesArg) noexcept + : nullableSelf { std::move(nullableSelfArg) } + , listSelves { std::move(listSelvesArg) } +{ +} + +ForwardDeclaredInput::ForwardDeclaredInput(const ForwardDeclaredInput& other) + : nullableSelf { service::ModifiedArgument::duplicate(other.nullableSelf) } + , listSelves { service::ModifiedArgument::duplicate(other.listSelves) } +{ +} + +ForwardDeclaredInput::ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept + : nullableSelf { std::move(other.nullableSelf) } + , listSelves { std::move(other.listSelves) } +{ +} + +ForwardDeclaredInput::~ForwardDeclaredInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ForwardDeclaredInput& ForwardDeclaredInput::operator=(const ForwardDeclaredInput& other) +{ + ForwardDeclaredInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ForwardDeclaredInput& ForwardDeclaredInput::operator=(ForwardDeclaredInput&& other) noexcept +{ + nullableSelf = std::move(other.nullableSelf); + listSelves = std::move(other.listSelves); + + return *this; +} + + +FirstNestedInput::FirstNestedInput() noexcept + : id {} + , second {} + , third {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +FirstNestedInput::FirstNestedInput( + response::IdType idArg, + SecondNestedInput secondArg, + ThirdNestedInput thirdArg) noexcept + : id { std::move(idArg) } + , second { std::move(secondArg) } + , third { std::move(thirdArg) } +{ +} + +FirstNestedInput::FirstNestedInput(const FirstNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , second { service::ModifiedArgument::duplicate(other.second) } + , third { service::ModifiedArgument::duplicate(other.third) } +{ +} + +FirstNestedInput::FirstNestedInput(FirstNestedInput&& other) noexcept + : id { std::move(other.id) } + , second { std::move(other.second) } + , third { std::move(other.third) } +{ +} + +FirstNestedInput::~FirstNestedInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +FirstNestedInput& FirstNestedInput::operator=(const FirstNestedInput& other) +{ + FirstNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +FirstNestedInput& FirstNestedInput::operator=(FirstNestedInput&& other) noexcept +{ + id = std::move(other.id); + second = std::move(other.second); + third = std::move(other.third); + + return *this; +} + +} // namespace today +} // namespace graphql diff --git a/samples/today/nointrospection/today_nointrospection_schema_files b/samples/today/nointrospection/today_nointrospection_schema_files index a9ed9ecf..2e24cdcf 100644 --- a/samples/today/nointrospection/today_nointrospection_schema_files +++ b/samples/today/nointrospection/today_nointrospection_schema_files @@ -1,3 +1,4 @@ +TodaySharedTypes.cpp TodaySchema.cpp NodeObject.cpp UnionTypeObject.cpp diff --git a/samples/today/schema/TodaySchema.cpp b/samples/today/schema/TodaySchema.cpp index f55a0831..b2395a64 100644 --- a/samples/today/schema/TodaySchema.cpp +++ b/samples/today/schema/TodaySchema.cpp @@ -22,711 +22,7 @@ using namespace std::literals; -namespace graphql { -namespace service { - -static const auto s_namesTaskState = today::getTaskStateNames(); -static const auto s_valuesTaskState = today::getTaskStateValues(); - -template <> -today::TaskState Argument::convert(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; - } - - const auto result = internal::sorted_map_lookup( - s_valuesTaskState, - std::string_view { value.get() }); - - if (!result) - { - throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; - } - - return *result; -} - -template <> -service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) -{ - return ModifiedResult::resolve(std::move(result), std::move(params), - [](today::TaskState value, const ResolverParams&) - { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); - - return resolvedResult; - }); -} - -template <> -void Result::validateScalar(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; - } - - const auto [itr, itrEnd] = internal::sorted_map_equal_range( - s_valuesTaskState.begin(), - s_valuesTaskState.end(), - std::string_view { value.get() }); - - if (itr == itrEnd) - { - throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; - } -} - -template <> -today::CompleteTaskInput Argument::convert(const response::Value& value) -{ - const auto defaultValue = []() - { - response::Value values(response::Type::Map); - response::Value entry; - - entry = response::Value(true); - values.emplace_back("isComplete", std::move(entry)); - - return values; - }(); - - auto valueId = service::ModifiedArgument::require("id", value); - auto valueTestTaskState = service::ModifiedArgument::require("testTaskState", value); - auto pairIsComplete = service::ModifiedArgument::find("isComplete", value); - auto valueIsComplete = (pairIsComplete.second - ? std::move(pairIsComplete.first) - : service::ModifiedArgument::require("isComplete", defaultValue)); - auto valueClientMutationId = service::ModifiedArgument::require("clientMutationId", value); - - return today::CompleteTaskInput { - std::move(valueId), - valueTestTaskState, - std::move(valueIsComplete), - std::move(valueClientMutationId) - }; -} - -template <> -today::ThirdNestedInput Argument::convert(const response::Value& value) -{ - auto valueId = service::ModifiedArgument::require("id", value); - auto valueSecond = service::ModifiedArgument::require("second", value); - - return today::ThirdNestedInput { - std::move(valueId), - std::move(valueSecond) - }; -} - -template <> -today::FourthNestedInput Argument::convert(const response::Value& value) -{ - auto valueId = service::ModifiedArgument::require("id", value); - - return today::FourthNestedInput { - std::move(valueId) - }; -} - -template <> -today::IncludeNullableSelfInput Argument::convert(const response::Value& value) -{ - auto valueSelf = service::ModifiedArgument::require("self", value); - - return today::IncludeNullableSelfInput { - std::move(valueSelf) - }; -} - -template <> -today::IncludeNonNullableListSelfInput Argument::convert(const response::Value& value) -{ - auto valueSelves = service::ModifiedArgument::require("selves", value); - - return today::IncludeNonNullableListSelfInput { - std::move(valueSelves) - }; -} - -template <> -today::StringOperationFilterInput Argument::convert(const response::Value& value) -{ - auto valueAnd_ = service::ModifiedArgument::require("and", value); - auto valueOr_ = service::ModifiedArgument::require("or", value); - auto valueEqual = service::ModifiedArgument::require("equal", value); - auto valueNotEqual = service::ModifiedArgument::require("notEqual", value); - auto valueContains = service::ModifiedArgument::require("contains", value); - auto valueNotContains = service::ModifiedArgument::require("notContains", value); - auto valueIn = service::ModifiedArgument::require("in", value); - auto valueNotIn = service::ModifiedArgument::require("notIn", value); - auto valueStartsWith = service::ModifiedArgument::require("startsWith", value); - auto valueNotStartsWith = service::ModifiedArgument::require("notStartsWith", value); - auto valueEndsWith = service::ModifiedArgument::require("endsWith", value); - auto valueNotEndsWith = service::ModifiedArgument::require("notEndsWith", value); - - return today::StringOperationFilterInput { - std::move(valueAnd_), - std::move(valueOr_), - std::move(valueEqual), - std::move(valueNotEqual), - std::move(valueContains), - std::move(valueNotContains), - std::move(valueIn), - std::move(valueNotIn), - std::move(valueStartsWith), - std::move(valueNotStartsWith), - std::move(valueEndsWith), - std::move(valueNotEndsWith) - }; -} - -template <> -today::SecondNestedInput Argument::convert(const response::Value& value) -{ - auto valueId = service::ModifiedArgument::require("id", value); - auto valueThird = service::ModifiedArgument::require("third", value); - - return today::SecondNestedInput { - std::move(valueId), - std::move(valueThird) - }; -} - -template <> -today::ForwardDeclaredInput Argument::convert(const response::Value& value) -{ - auto valueNullableSelf = service::ModifiedArgument::require("nullableSelf", value); - auto valueListSelves = service::ModifiedArgument::require("listSelves", value); - - return today::ForwardDeclaredInput { - std::move(valueNullableSelf), - std::move(valueListSelves) - }; -} - -template <> -today::FirstNestedInput Argument::convert(const response::Value& value) -{ - auto valueId = service::ModifiedArgument::require("id", value); - auto valueSecond = service::ModifiedArgument::require("second", value); - auto valueThird = service::ModifiedArgument::require("third", value); - - return today::FirstNestedInput { - std::move(valueId), - std::move(valueSecond), - std::move(valueThird) - }; -} - -} // namespace service - -namespace today { - -CompleteTaskInput::CompleteTaskInput() noexcept - : id {} - , testTaskState {} - , isComplete {} - , clientMutationId {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -CompleteTaskInput::CompleteTaskInput( - response::IdType idArg, - std::optional testTaskStateArg, - std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept - : id { std::move(idArg) } - , testTaskState { std::move(testTaskStateArg) } - , isComplete { std::move(isCompleteArg) } - , clientMutationId { std::move(clientMutationIdArg) } -{ -} - -CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) - : id { service::ModifiedArgument::duplicate(other.id) } - , testTaskState { service::ModifiedArgument::duplicate(other.testTaskState) } - , isComplete { service::ModifiedArgument::duplicate(other.isComplete) } - , clientMutationId { service::ModifiedArgument::duplicate(other.clientMutationId) } -{ -} - -CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept - : id { std::move(other.id) } - , testTaskState { std::move(other.testTaskState) } - , isComplete { std::move(other.isComplete) } - , clientMutationId { std::move(other.clientMutationId) } -{ -} - -CompleteTaskInput::~CompleteTaskInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -CompleteTaskInput& CompleteTaskInput::operator=(const CompleteTaskInput& other) -{ - CompleteTaskInput value { other }; - - std::swap(*this, value); - - return *this; -} - -CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexcept -{ - id = std::move(other.id); - testTaskState = std::move(other.testTaskState); - isComplete = std::move(other.isComplete); - clientMutationId = std::move(other.clientMutationId); - - return *this; -} - -ThirdNestedInput::ThirdNestedInput() noexcept - : id {} - , second {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ThirdNestedInput::ThirdNestedInput( - response::IdType idArg, - std::unique_ptr secondArg) noexcept - : id { std::move(idArg) } - , second { std::move(secondArg) } -{ -} - -ThirdNestedInput::ThirdNestedInput(const ThirdNestedInput& other) - : id { service::ModifiedArgument::duplicate(other.id) } - , second { service::ModifiedArgument::duplicate(other.second) } -{ -} - -ThirdNestedInput::ThirdNestedInput(ThirdNestedInput&& other) noexcept - : id { std::move(other.id) } - , second { std::move(other.second) } -{ -} - -ThirdNestedInput::~ThirdNestedInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ThirdNestedInput& ThirdNestedInput::operator=(const ThirdNestedInput& other) -{ - ThirdNestedInput value { other }; - - std::swap(*this, value); - - return *this; -} - -ThirdNestedInput& ThirdNestedInput::operator=(ThirdNestedInput&& other) noexcept -{ - id = std::move(other.id); - second = std::move(other.second); - - return *this; -} - -FourthNestedInput::FourthNestedInput() noexcept - : id {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -FourthNestedInput::FourthNestedInput( - response::IdType idArg) noexcept - : id { std::move(idArg) } -{ -} - -FourthNestedInput::FourthNestedInput(const FourthNestedInput& other) - : id { service::ModifiedArgument::duplicate(other.id) } -{ -} - -FourthNestedInput::FourthNestedInput(FourthNestedInput&& other) noexcept - : id { std::move(other.id) } -{ -} - -FourthNestedInput::~FourthNestedInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -FourthNestedInput& FourthNestedInput::operator=(const FourthNestedInput& other) -{ - FourthNestedInput value { other }; - - std::swap(*this, value); - - return *this; -} - -FourthNestedInput& FourthNestedInput::operator=(FourthNestedInput&& other) noexcept -{ - id = std::move(other.id); - - return *this; -} - -IncludeNullableSelfInput::IncludeNullableSelfInput() noexcept - : self {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -IncludeNullableSelfInput::IncludeNullableSelfInput( - std::unique_ptr selfArg) noexcept - : self { std::move(selfArg) } -{ -} - -IncludeNullableSelfInput::IncludeNullableSelfInput(const IncludeNullableSelfInput& other) - : self { service::ModifiedArgument::duplicate(other.self) } -{ -} - -IncludeNullableSelfInput::IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept - : self { std::move(other.self) } -{ -} - -IncludeNullableSelfInput::~IncludeNullableSelfInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(const IncludeNullableSelfInput& other) -{ - IncludeNullableSelfInput value { other }; - - std::swap(*this, value); - - return *this; -} - -IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(IncludeNullableSelfInput&& other) noexcept -{ - self = std::move(other.self); - - return *this; -} - -IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput() noexcept - : selves {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput( - std::vector selvesArg) noexcept - : selves { std::move(selvesArg) } -{ -} - -IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other) - : selves { service::ModifiedArgument::duplicate(other.selves) } -{ -} - -IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept - : selves { std::move(other.selves) } -{ -} - -IncludeNonNullableListSelfInput::~IncludeNonNullableListSelfInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(const IncludeNonNullableListSelfInput& other) -{ - IncludeNonNullableListSelfInput value { other }; - - std::swap(*this, value); - - return *this; -} - -IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(IncludeNonNullableListSelfInput&& other) noexcept -{ - selves = std::move(other.selves); - - return *this; -} - -StringOperationFilterInput::StringOperationFilterInput() noexcept - : and_ {} - , or_ {} - , equal {} - , notEqual {} - , contains {} - , notContains {} - , in {} - , notIn {} - , startsWith {} - , notStartsWith {} - , endsWith {} - , notEndsWith {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -StringOperationFilterInput::StringOperationFilterInput( - std::optional> and_Arg, - std::optional> or_Arg, - std::optional equalArg, - std::optional notEqualArg, - std::optional containsArg, - std::optional notContainsArg, - std::optional> inArg, - std::optional> notInArg, - std::optional startsWithArg, - std::optional notStartsWithArg, - std::optional endsWithArg, - std::optional notEndsWithArg) noexcept - : and_ { std::move(and_Arg) } - , or_ { std::move(or_Arg) } - , equal { std::move(equalArg) } - , notEqual { std::move(notEqualArg) } - , contains { std::move(containsArg) } - , notContains { std::move(notContainsArg) } - , in { std::move(inArg) } - , notIn { std::move(notInArg) } - , startsWith { std::move(startsWithArg) } - , notStartsWith { std::move(notStartsWithArg) } - , endsWith { std::move(endsWithArg) } - , notEndsWith { std::move(notEndsWithArg) } -{ -} - -StringOperationFilterInput::StringOperationFilterInput(const StringOperationFilterInput& other) - : and_ { service::ModifiedArgument::duplicate(other.and_) } - , or_ { service::ModifiedArgument::duplicate(other.or_) } - , equal { service::ModifiedArgument::duplicate(other.equal) } - , notEqual { service::ModifiedArgument::duplicate(other.notEqual) } - , contains { service::ModifiedArgument::duplicate(other.contains) } - , notContains { service::ModifiedArgument::duplicate(other.notContains) } - , in { service::ModifiedArgument::duplicate(other.in) } - , notIn { service::ModifiedArgument::duplicate(other.notIn) } - , startsWith { service::ModifiedArgument::duplicate(other.startsWith) } - , notStartsWith { service::ModifiedArgument::duplicate(other.notStartsWith) } - , endsWith { service::ModifiedArgument::duplicate(other.endsWith) } - , notEndsWith { service::ModifiedArgument::duplicate(other.notEndsWith) } -{ -} - -StringOperationFilterInput::StringOperationFilterInput(StringOperationFilterInput&& other) noexcept - : and_ { std::move(other.and_) } - , or_ { std::move(other.or_) } - , equal { std::move(other.equal) } - , notEqual { std::move(other.notEqual) } - , contains { std::move(other.contains) } - , notContains { std::move(other.notContains) } - , in { std::move(other.in) } - , notIn { std::move(other.notIn) } - , startsWith { std::move(other.startsWith) } - , notStartsWith { std::move(other.notStartsWith) } - , endsWith { std::move(other.endsWith) } - , notEndsWith { std::move(other.notEndsWith) } -{ -} - -StringOperationFilterInput::~StringOperationFilterInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -StringOperationFilterInput& StringOperationFilterInput::operator=(const StringOperationFilterInput& other) -{ - StringOperationFilterInput value { other }; - - std::swap(*this, value); - - return *this; -} - -StringOperationFilterInput& StringOperationFilterInput::operator=(StringOperationFilterInput&& other) noexcept -{ - and_ = std::move(other.and_); - or_ = std::move(other.or_); - equal = std::move(other.equal); - notEqual = std::move(other.notEqual); - contains = std::move(other.contains); - notContains = std::move(other.notContains); - in = std::move(other.in); - notIn = std::move(other.notIn); - startsWith = std::move(other.startsWith); - notStartsWith = std::move(other.notStartsWith); - endsWith = std::move(other.endsWith); - notEndsWith = std::move(other.notEndsWith); - - return *this; -} - -SecondNestedInput::SecondNestedInput() noexcept - : id {} - , third {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -SecondNestedInput::SecondNestedInput( - response::IdType idArg, - ThirdNestedInput thirdArg) noexcept - : id { std::move(idArg) } - , third { std::move(thirdArg) } -{ -} - -SecondNestedInput::SecondNestedInput(const SecondNestedInput& other) - : id { service::ModifiedArgument::duplicate(other.id) } - , third { service::ModifiedArgument::duplicate(other.third) } -{ -} - -SecondNestedInput::SecondNestedInput(SecondNestedInput&& other) noexcept - : id { std::move(other.id) } - , third { std::move(other.third) } -{ -} - -SecondNestedInput::~SecondNestedInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -SecondNestedInput& SecondNestedInput::operator=(const SecondNestedInput& other) -{ - SecondNestedInput value { other }; - - std::swap(*this, value); - - return *this; -} - -SecondNestedInput& SecondNestedInput::operator=(SecondNestedInput&& other) noexcept -{ - id = std::move(other.id); - third = std::move(other.third); - - return *this; -} - -ForwardDeclaredInput::ForwardDeclaredInput() noexcept - : nullableSelf {} - , listSelves {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ForwardDeclaredInput::ForwardDeclaredInput( - std::unique_ptr nullableSelfArg, - IncludeNonNullableListSelfInput listSelvesArg) noexcept - : nullableSelf { std::move(nullableSelfArg) } - , listSelves { std::move(listSelvesArg) } -{ -} - -ForwardDeclaredInput::ForwardDeclaredInput(const ForwardDeclaredInput& other) - : nullableSelf { service::ModifiedArgument::duplicate(other.nullableSelf) } - , listSelves { service::ModifiedArgument::duplicate(other.listSelves) } -{ -} - -ForwardDeclaredInput::ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept - : nullableSelf { std::move(other.nullableSelf) } - , listSelves { std::move(other.listSelves) } -{ -} - -ForwardDeclaredInput::~ForwardDeclaredInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ForwardDeclaredInput& ForwardDeclaredInput::operator=(const ForwardDeclaredInput& other) -{ - ForwardDeclaredInput value { other }; - - std::swap(*this, value); - - return *this; -} - -ForwardDeclaredInput& ForwardDeclaredInput::operator=(ForwardDeclaredInput&& other) noexcept -{ - nullableSelf = std::move(other.nullableSelf); - listSelves = std::move(other.listSelves); - - return *this; -} - -FirstNestedInput::FirstNestedInput() noexcept - : id {} - , second {} - , third {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -FirstNestedInput::FirstNestedInput( - response::IdType idArg, - SecondNestedInput secondArg, - ThirdNestedInput thirdArg) noexcept - : id { std::move(idArg) } - , second { std::move(secondArg) } - , third { std::move(thirdArg) } -{ -} - -FirstNestedInput::FirstNestedInput(const FirstNestedInput& other) - : id { service::ModifiedArgument::duplicate(other.id) } - , second { service::ModifiedArgument::duplicate(other.second) } - , third { service::ModifiedArgument::duplicate(other.third) } -{ -} - -FirstNestedInput::FirstNestedInput(FirstNestedInput&& other) noexcept - : id { std::move(other.id) } - , second { std::move(other.second) } - , third { std::move(other.third) } -{ -} - -FirstNestedInput::~FirstNestedInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -FirstNestedInput& FirstNestedInput::operator=(const FirstNestedInput& other) -{ - FirstNestedInput value { other }; - - std::swap(*this, value); - - return *this; -} - -FirstNestedInput& FirstNestedInput::operator=(FirstNestedInput&& other) noexcept -{ - id = std::move(other.id); - second = std::move(other.second); - third = std::move(other.third); - - return *this; -} +namespace graphql::today { Operations::Operations(std::shared_ptr query, std::shared_ptr mutation, std::shared_ptr subscription) : service::Request({ @@ -804,11 +100,13 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeExpensive = schema::ObjectType::Make(R"gql(Expensive)gql"sv, R"md()md"sv); schema->AddType(R"gql(Expensive)gql"sv, typeExpensive); + + static const auto s_namesTaskState = getTaskStateNames(); typeTaskState->AddEnumValues({ - { service::s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, - { service::s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } + { s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, + { s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, + { s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, + { s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } }); typeCompleteTaskInput->AddInputValues({ @@ -932,5 +230,4 @@ std::shared_ptr GetSchema() return schema; } -} // namespace today -} // namespace graphql +} // namespace graphql::today diff --git a/samples/today/schema/TodaySharedTypes.cpp b/samples/today/schema/TodaySharedTypes.cpp new file mode 100644 index 00000000..d3a0c4a0 --- /dev/null +++ b/samples/today/schema/TodaySharedTypes.cpp @@ -0,0 +1,736 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#include "graphqlservice/GraphQLService.h" + +#include "TodaySharedTypes.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace graphql { +namespace service { + +static const auto s_namesTaskState = today::getTaskStateNames(); +static const auto s_valuesTaskState = today::getTaskStateValues(); + +template <> +today::TaskState Argument::convert(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; + } + + const auto result = internal::sorted_map_lookup( + s_valuesTaskState, + std::string_view { value.get() }); + + if (!result) + { + throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; + } + + return *result; +} + +template <> +service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), std::move(params), + [](today::TaskState value, const ResolverParams&) + { + response::Value resolvedResult(response::Type::EnumValue); + + resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); + + return resolvedResult; + }); +} + +template <> +void Result::validateScalar(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; + } + + const auto [itr, itrEnd] = internal::sorted_map_equal_range( + s_valuesTaskState.begin(), + s_valuesTaskState.end(), + std::string_view { value.get() }); + + if (itr == itrEnd) + { + throw service::schema_exception { { R"ex(not a valid TaskState value)ex" } }; + } +} + +template <> +today::CompleteTaskInput Argument::convert(const response::Value& value) +{ + const auto defaultValue = []() + { + response::Value values(response::Type::Map); + response::Value entry; + + entry = response::Value(true); + values.emplace_back("isComplete", std::move(entry)); + + return values; + }(); + + auto valueId = service::ModifiedArgument::require("id", value); + auto valueTestTaskState = service::ModifiedArgument::require("testTaskState", value); + auto pairIsComplete = service::ModifiedArgument::find("isComplete", value); + auto valueIsComplete = (pairIsComplete.second + ? std::move(pairIsComplete.first) + : service::ModifiedArgument::require("isComplete", defaultValue)); + auto valueClientMutationId = service::ModifiedArgument::require("clientMutationId", value); + + return today::CompleteTaskInput { + std::move(valueId), + valueTestTaskState, + std::move(valueIsComplete), + std::move(valueClientMutationId) + }; +} + +template <> +today::ThirdNestedInput Argument::convert(const response::Value& value) +{ + auto valueId = service::ModifiedArgument::require("id", value); + auto valueSecond = service::ModifiedArgument::require("second", value); + + return today::ThirdNestedInput { + std::move(valueId), + std::move(valueSecond) + }; +} + +template <> +today::FourthNestedInput Argument::convert(const response::Value& value) +{ + auto valueId = service::ModifiedArgument::require("id", value); + + return today::FourthNestedInput { + std::move(valueId) + }; +} + +template <> +today::IncludeNullableSelfInput Argument::convert(const response::Value& value) +{ + auto valueSelf = service::ModifiedArgument::require("self", value); + + return today::IncludeNullableSelfInput { + std::move(valueSelf) + }; +} + +template <> +today::IncludeNonNullableListSelfInput Argument::convert(const response::Value& value) +{ + auto valueSelves = service::ModifiedArgument::require("selves", value); + + return today::IncludeNonNullableListSelfInput { + std::move(valueSelves) + }; +} + +template <> +today::StringOperationFilterInput Argument::convert(const response::Value& value) +{ + auto valueAnd_ = service::ModifiedArgument::require("and", value); + auto valueOr_ = service::ModifiedArgument::require("or", value); + auto valueEqual = service::ModifiedArgument::require("equal", value); + auto valueNotEqual = service::ModifiedArgument::require("notEqual", value); + auto valueContains = service::ModifiedArgument::require("contains", value); + auto valueNotContains = service::ModifiedArgument::require("notContains", value); + auto valueIn = service::ModifiedArgument::require("in", value); + auto valueNotIn = service::ModifiedArgument::require("notIn", value); + auto valueStartsWith = service::ModifiedArgument::require("startsWith", value); + auto valueNotStartsWith = service::ModifiedArgument::require("notStartsWith", value); + auto valueEndsWith = service::ModifiedArgument::require("endsWith", value); + auto valueNotEndsWith = service::ModifiedArgument::require("notEndsWith", value); + + return today::StringOperationFilterInput { + std::move(valueAnd_), + std::move(valueOr_), + std::move(valueEqual), + std::move(valueNotEqual), + std::move(valueContains), + std::move(valueNotContains), + std::move(valueIn), + std::move(valueNotIn), + std::move(valueStartsWith), + std::move(valueNotStartsWith), + std::move(valueEndsWith), + std::move(valueNotEndsWith) + }; +} + +template <> +today::SecondNestedInput Argument::convert(const response::Value& value) +{ + auto valueId = service::ModifiedArgument::require("id", value); + auto valueThird = service::ModifiedArgument::require("third", value); + + return today::SecondNestedInput { + std::move(valueId), + std::move(valueThird) + }; +} + +template <> +today::ForwardDeclaredInput Argument::convert(const response::Value& value) +{ + auto valueNullableSelf = service::ModifiedArgument::require("nullableSelf", value); + auto valueListSelves = service::ModifiedArgument::require("listSelves", value); + + return today::ForwardDeclaredInput { + std::move(valueNullableSelf), + std::move(valueListSelves) + }; +} + +template <> +today::FirstNestedInput Argument::convert(const response::Value& value) +{ + auto valueId = service::ModifiedArgument::require("id", value); + auto valueSecond = service::ModifiedArgument::require("second", value); + auto valueThird = service::ModifiedArgument::require("third", value); + + return today::FirstNestedInput { + std::move(valueId), + std::move(valueSecond), + std::move(valueThird) + }; +} + +} // namespace service + +namespace today { + +CompleteTaskInput::CompleteTaskInput() noexcept + : id {} + , testTaskState {} + , isComplete {} + , clientMutationId {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +CompleteTaskInput::CompleteTaskInput( + response::IdType idArg, + std::optional testTaskStateArg, + std::optional isCompleteArg, + std::optional clientMutationIdArg) noexcept + : id { std::move(idArg) } + , testTaskState { std::move(testTaskStateArg) } + , isComplete { std::move(isCompleteArg) } + , clientMutationId { std::move(clientMutationIdArg) } +{ +} + +CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , testTaskState { service::ModifiedArgument::duplicate(other.testTaskState) } + , isComplete { service::ModifiedArgument::duplicate(other.isComplete) } + , clientMutationId { service::ModifiedArgument::duplicate(other.clientMutationId) } +{ +} + +CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept + : id { std::move(other.id) } + , testTaskState { std::move(other.testTaskState) } + , isComplete { std::move(other.isComplete) } + , clientMutationId { std::move(other.clientMutationId) } +{ +} + +CompleteTaskInput::~CompleteTaskInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +CompleteTaskInput& CompleteTaskInput::operator=(const CompleteTaskInput& other) +{ + CompleteTaskInput value { other }; + + std::swap(*this, value); + + return *this; +} + +CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexcept +{ + id = std::move(other.id); + testTaskState = std::move(other.testTaskState); + isComplete = std::move(other.isComplete); + clientMutationId = std::move(other.clientMutationId); + + return *this; +} + + +ThirdNestedInput::ThirdNestedInput() noexcept + : id {} + , second {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ThirdNestedInput::ThirdNestedInput( + response::IdType idArg, + std::unique_ptr secondArg) noexcept + : id { std::move(idArg) } + , second { std::move(secondArg) } +{ +} + +ThirdNestedInput::ThirdNestedInput(const ThirdNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , second { service::ModifiedArgument::duplicate(other.second) } +{ +} + +ThirdNestedInput::ThirdNestedInput(ThirdNestedInput&& other) noexcept + : id { std::move(other.id) } + , second { std::move(other.second) } +{ +} + +ThirdNestedInput::~ThirdNestedInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ThirdNestedInput& ThirdNestedInput::operator=(const ThirdNestedInput& other) +{ + ThirdNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ThirdNestedInput& ThirdNestedInput::operator=(ThirdNestedInput&& other) noexcept +{ + id = std::move(other.id); + second = std::move(other.second); + + return *this; +} + + +FourthNestedInput::FourthNestedInput() noexcept + : id {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +FourthNestedInput::FourthNestedInput( + response::IdType idArg) noexcept + : id { std::move(idArg) } +{ +} + +FourthNestedInput::FourthNestedInput(const FourthNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } +{ +} + +FourthNestedInput::FourthNestedInput(FourthNestedInput&& other) noexcept + : id { std::move(other.id) } +{ +} + +FourthNestedInput::~FourthNestedInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +FourthNestedInput& FourthNestedInput::operator=(const FourthNestedInput& other) +{ + FourthNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +FourthNestedInput& FourthNestedInput::operator=(FourthNestedInput&& other) noexcept +{ + id = std::move(other.id); + + return *this; +} + + +IncludeNullableSelfInput::IncludeNullableSelfInput() noexcept + : self {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +IncludeNullableSelfInput::IncludeNullableSelfInput( + std::unique_ptr selfArg) noexcept + : self { std::move(selfArg) } +{ +} + +IncludeNullableSelfInput::IncludeNullableSelfInput(const IncludeNullableSelfInput& other) + : self { service::ModifiedArgument::duplicate(other.self) } +{ +} + +IncludeNullableSelfInput::IncludeNullableSelfInput(IncludeNullableSelfInput&& other) noexcept + : self { std::move(other.self) } +{ +} + +IncludeNullableSelfInput::~IncludeNullableSelfInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(const IncludeNullableSelfInput& other) +{ + IncludeNullableSelfInput value { other }; + + std::swap(*this, value); + + return *this; +} + +IncludeNullableSelfInput& IncludeNullableSelfInput::operator=(IncludeNullableSelfInput&& other) noexcept +{ + self = std::move(other.self); + + return *this; +} + + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput() noexcept + : selves {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput( + std::vector selvesArg) noexcept + : selves { std::move(selvesArg) } +{ +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(const IncludeNonNullableListSelfInput& other) + : selves { service::ModifiedArgument::duplicate(other.selves) } +{ +} + +IncludeNonNullableListSelfInput::IncludeNonNullableListSelfInput(IncludeNonNullableListSelfInput&& other) noexcept + : selves { std::move(other.selves) } +{ +} + +IncludeNonNullableListSelfInput::~IncludeNonNullableListSelfInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(const IncludeNonNullableListSelfInput& other) +{ + IncludeNonNullableListSelfInput value { other }; + + std::swap(*this, value); + + return *this; +} + +IncludeNonNullableListSelfInput& IncludeNonNullableListSelfInput::operator=(IncludeNonNullableListSelfInput&& other) noexcept +{ + selves = std::move(other.selves); + + return *this; +} + + +StringOperationFilterInput::StringOperationFilterInput() noexcept + : and_ {} + , or_ {} + , equal {} + , notEqual {} + , contains {} + , notContains {} + , in {} + , notIn {} + , startsWith {} + , notStartsWith {} + , endsWith {} + , notEndsWith {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +StringOperationFilterInput::StringOperationFilterInput( + std::optional> and_Arg, + std::optional> or_Arg, + std::optional equalArg, + std::optional notEqualArg, + std::optional containsArg, + std::optional notContainsArg, + std::optional> inArg, + std::optional> notInArg, + std::optional startsWithArg, + std::optional notStartsWithArg, + std::optional endsWithArg, + std::optional notEndsWithArg) noexcept + : and_ { std::move(and_Arg) } + , or_ { std::move(or_Arg) } + , equal { std::move(equalArg) } + , notEqual { std::move(notEqualArg) } + , contains { std::move(containsArg) } + , notContains { std::move(notContainsArg) } + , in { std::move(inArg) } + , notIn { std::move(notInArg) } + , startsWith { std::move(startsWithArg) } + , notStartsWith { std::move(notStartsWithArg) } + , endsWith { std::move(endsWithArg) } + , notEndsWith { std::move(notEndsWithArg) } +{ +} + +StringOperationFilterInput::StringOperationFilterInput(const StringOperationFilterInput& other) + : and_ { service::ModifiedArgument::duplicate(other.and_) } + , or_ { service::ModifiedArgument::duplicate(other.or_) } + , equal { service::ModifiedArgument::duplicate(other.equal) } + , notEqual { service::ModifiedArgument::duplicate(other.notEqual) } + , contains { service::ModifiedArgument::duplicate(other.contains) } + , notContains { service::ModifiedArgument::duplicate(other.notContains) } + , in { service::ModifiedArgument::duplicate(other.in) } + , notIn { service::ModifiedArgument::duplicate(other.notIn) } + , startsWith { service::ModifiedArgument::duplicate(other.startsWith) } + , notStartsWith { service::ModifiedArgument::duplicate(other.notStartsWith) } + , endsWith { service::ModifiedArgument::duplicate(other.endsWith) } + , notEndsWith { service::ModifiedArgument::duplicate(other.notEndsWith) } +{ +} + +StringOperationFilterInput::StringOperationFilterInput(StringOperationFilterInput&& other) noexcept + : and_ { std::move(other.and_) } + , or_ { std::move(other.or_) } + , equal { std::move(other.equal) } + , notEqual { std::move(other.notEqual) } + , contains { std::move(other.contains) } + , notContains { std::move(other.notContains) } + , in { std::move(other.in) } + , notIn { std::move(other.notIn) } + , startsWith { std::move(other.startsWith) } + , notStartsWith { std::move(other.notStartsWith) } + , endsWith { std::move(other.endsWith) } + , notEndsWith { std::move(other.notEndsWith) } +{ +} + +StringOperationFilterInput::~StringOperationFilterInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +StringOperationFilterInput& StringOperationFilterInput::operator=(const StringOperationFilterInput& other) +{ + StringOperationFilterInput value { other }; + + std::swap(*this, value); + + return *this; +} + +StringOperationFilterInput& StringOperationFilterInput::operator=(StringOperationFilterInput&& other) noexcept +{ + and_ = std::move(other.and_); + or_ = std::move(other.or_); + equal = std::move(other.equal); + notEqual = std::move(other.notEqual); + contains = std::move(other.contains); + notContains = std::move(other.notContains); + in = std::move(other.in); + notIn = std::move(other.notIn); + startsWith = std::move(other.startsWith); + notStartsWith = std::move(other.notStartsWith); + endsWith = std::move(other.endsWith); + notEndsWith = std::move(other.notEndsWith); + + return *this; +} + + +SecondNestedInput::SecondNestedInput() noexcept + : id {} + , third {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +SecondNestedInput::SecondNestedInput( + response::IdType idArg, + ThirdNestedInput thirdArg) noexcept + : id { std::move(idArg) } + , third { std::move(thirdArg) } +{ +} + +SecondNestedInput::SecondNestedInput(const SecondNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , third { service::ModifiedArgument::duplicate(other.third) } +{ +} + +SecondNestedInput::SecondNestedInput(SecondNestedInput&& other) noexcept + : id { std::move(other.id) } + , third { std::move(other.third) } +{ +} + +SecondNestedInput::~SecondNestedInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +SecondNestedInput& SecondNestedInput::operator=(const SecondNestedInput& other) +{ + SecondNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +SecondNestedInput& SecondNestedInput::operator=(SecondNestedInput&& other) noexcept +{ + id = std::move(other.id); + third = std::move(other.third); + + return *this; +} + + +ForwardDeclaredInput::ForwardDeclaredInput() noexcept + : nullableSelf {} + , listSelves {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ForwardDeclaredInput::ForwardDeclaredInput( + std::unique_ptr nullableSelfArg, + IncludeNonNullableListSelfInput listSelvesArg) noexcept + : nullableSelf { std::move(nullableSelfArg) } + , listSelves { std::move(listSelvesArg) } +{ +} + +ForwardDeclaredInput::ForwardDeclaredInput(const ForwardDeclaredInput& other) + : nullableSelf { service::ModifiedArgument::duplicate(other.nullableSelf) } + , listSelves { service::ModifiedArgument::duplicate(other.listSelves) } +{ +} + +ForwardDeclaredInput::ForwardDeclaredInput(ForwardDeclaredInput&& other) noexcept + : nullableSelf { std::move(other.nullableSelf) } + , listSelves { std::move(other.listSelves) } +{ +} + +ForwardDeclaredInput::~ForwardDeclaredInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ForwardDeclaredInput& ForwardDeclaredInput::operator=(const ForwardDeclaredInput& other) +{ + ForwardDeclaredInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ForwardDeclaredInput& ForwardDeclaredInput::operator=(ForwardDeclaredInput&& other) noexcept +{ + nullableSelf = std::move(other.nullableSelf); + listSelves = std::move(other.listSelves); + + return *this; +} + + +FirstNestedInput::FirstNestedInput() noexcept + : id {} + , second {} + , third {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +FirstNestedInput::FirstNestedInput( + response::IdType idArg, + SecondNestedInput secondArg, + ThirdNestedInput thirdArg) noexcept + : id { std::move(idArg) } + , second { std::move(secondArg) } + , third { std::move(thirdArg) } +{ +} + +FirstNestedInput::FirstNestedInput(const FirstNestedInput& other) + : id { service::ModifiedArgument::duplicate(other.id) } + , second { service::ModifiedArgument::duplicate(other.second) } + , third { service::ModifiedArgument::duplicate(other.third) } +{ +} + +FirstNestedInput::FirstNestedInput(FirstNestedInput&& other) noexcept + : id { std::move(other.id) } + , second { std::move(other.second) } + , third { std::move(other.third) } +{ +} + +FirstNestedInput::~FirstNestedInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +FirstNestedInput& FirstNestedInput::operator=(const FirstNestedInput& other) +{ + FirstNestedInput value { other }; + + std::swap(*this, value); + + return *this; +} + +FirstNestedInput& FirstNestedInput::operator=(FirstNestedInput&& other) noexcept +{ + id = std::move(other.id); + second = std::move(other.second); + third = std::move(other.third); + + return *this; +} + +} // namespace today +} // namespace graphql diff --git a/samples/today/schema/today_schema_files b/samples/today/schema/today_schema_files index a9ed9ecf..2e24cdcf 100644 --- a/samples/today/schema/today_schema_files +++ b/samples/today/schema/today_schema_files @@ -1,3 +1,4 @@ +TodaySharedTypes.cpp TodaySchema.cpp NodeObject.cpp UnionTypeObject.cpp diff --git a/samples/validation/schema/ValidationSchema.cpp b/samples/validation/schema/ValidationSchema.cpp index bc7c42b8..463eccda 100644 --- a/samples/validation/schema/ValidationSchema.cpp +++ b/samples/validation/schema/ValidationSchema.cpp @@ -22,185 +22,7 @@ using namespace std::literals; -namespace graphql { -namespace service { - -static const auto s_namesDogCommand = validation::getDogCommandNames(); -static const auto s_valuesDogCommand = validation::getDogCommandValues(); - -template <> -validation::DogCommand Argument::convert(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid DogCommand value)ex" } }; - } - - const auto result = internal::sorted_map_lookup( - s_valuesDogCommand, - std::string_view { value.get() }); - - if (!result) - { - throw service::schema_exception { { R"ex(not a valid DogCommand value)ex" } }; - } - - return *result; -} - -template <> -service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) -{ - return ModifiedResult::resolve(std::move(result), std::move(params), - [](validation::DogCommand value, const ResolverParams&) - { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesDogCommand[static_cast(value)] }); - - return resolvedResult; - }); -} - -template <> -void Result::validateScalar(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid DogCommand value)ex" } }; - } - - const auto [itr, itrEnd] = internal::sorted_map_equal_range( - s_valuesDogCommand.begin(), - s_valuesDogCommand.end(), - std::string_view { value.get() }); - - if (itr == itrEnd) - { - throw service::schema_exception { { R"ex(not a valid DogCommand value)ex" } }; - } -} - -static const auto s_namesCatCommand = validation::getCatCommandNames(); -static const auto s_valuesCatCommand = validation::getCatCommandValues(); - -template <> -validation::CatCommand Argument::convert(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid CatCommand value)ex" } }; - } - - const auto result = internal::sorted_map_lookup( - s_valuesCatCommand, - std::string_view { value.get() }); - - if (!result) - { - throw service::schema_exception { { R"ex(not a valid CatCommand value)ex" } }; - } - - return *result; -} - -template <> -service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) -{ - return ModifiedResult::resolve(std::move(result), std::move(params), - [](validation::CatCommand value, const ResolverParams&) - { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesCatCommand[static_cast(value)] }); - - return resolvedResult; - }); -} - -template <> -void Result::validateScalar(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid CatCommand value)ex" } }; - } - - const auto [itr, itrEnd] = internal::sorted_map_equal_range( - s_valuesCatCommand.begin(), - s_valuesCatCommand.end(), - std::string_view { value.get() }); - - if (itr == itrEnd) - { - throw service::schema_exception { { R"ex(not a valid CatCommand value)ex" } }; - } -} - -template <> -validation::ComplexInput Argument::convert(const response::Value& value) -{ - auto valueName = service::ModifiedArgument::require("name", value); - auto valueOwner = service::ModifiedArgument::require("owner", value); - - return validation::ComplexInput { - std::move(valueName), - std::move(valueOwner) - }; -} - -} // namespace service - -namespace validation { - -ComplexInput::ComplexInput() noexcept - : name {} - , owner {} -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ComplexInput::ComplexInput( - std::optional nameArg, - std::optional ownerArg) noexcept - : name { std::move(nameArg) } - , owner { std::move(ownerArg) } -{ -} - -ComplexInput::ComplexInput(const ComplexInput& other) - : name { service::ModifiedArgument::duplicate(other.name) } - , owner { service::ModifiedArgument::duplicate(other.owner) } -{ -} - -ComplexInput::ComplexInput(ComplexInput&& other) noexcept - : name { std::move(other.name) } - , owner { std::move(other.owner) } -{ -} - -ComplexInput::~ComplexInput() -{ - // Explicit definition to prevent ODR violations when LTO is enabled. -} - -ComplexInput& ComplexInput::operator=(const ComplexInput& other) -{ - ComplexInput value { other }; - - std::swap(*this, value); - - return *this; -} - -ComplexInput& ComplexInput::operator=(ComplexInput&& other) noexcept -{ - name = std::move(other.name); - owner = std::move(other.owner); - - return *this; -} +namespace graphql::validation { Operations::Operations(std::shared_ptr query, std::shared_ptr mutation, std::shared_ptr subscription) : service::Request({ @@ -257,13 +79,17 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeArguments = schema::ObjectType::Make(R"gql(Arguments)gql"sv, R"md()md"sv); schema->AddType(R"gql(Arguments)gql"sv, typeArguments); + + static const auto s_namesDogCommand = getDogCommandNames(); typeDogCommand->AddEnumValues({ - { service::s_namesDogCommand[static_cast(validation::DogCommand::SIT)], R"md()md"sv, std::nullopt }, - { service::s_namesDogCommand[static_cast(validation::DogCommand::DOWN)], R"md()md"sv, std::nullopt }, - { service::s_namesDogCommand[static_cast(validation::DogCommand::HEEL)], R"md()md"sv, std::nullopt } + { s_namesDogCommand[static_cast(validation::DogCommand::SIT)], R"md()md"sv, std::nullopt }, + { s_namesDogCommand[static_cast(validation::DogCommand::DOWN)], R"md()md"sv, std::nullopt }, + { s_namesDogCommand[static_cast(validation::DogCommand::HEEL)], R"md()md"sv, std::nullopt } }); + + static const auto s_namesCatCommand = getCatCommandNames(); typeCatCommand->AddEnumValues({ - { service::s_namesCatCommand[static_cast(validation::CatCommand::JUMP)], R"md()md"sv, std::nullopt } + { s_namesCatCommand[static_cast(validation::CatCommand::JUMP)], R"md()md"sv, std::nullopt } }); typeComplexInput->AddInputValues({ @@ -312,5 +138,4 @@ std::shared_ptr GetSchema() return schema; } -} // namespace validation -} // namespace graphql +} // namespace graphql::validation diff --git a/samples/validation/schema/ValidationSharedTypes.cpp b/samples/validation/schema/ValidationSharedTypes.cpp new file mode 100644 index 00000000..47c18527 --- /dev/null +++ b/samples/validation/schema/ValidationSharedTypes.cpp @@ -0,0 +1,202 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#include "graphqlservice/GraphQLService.h" + +#include "ValidationSharedTypes.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace graphql { +namespace service { + +static const auto s_namesDogCommand = validation::getDogCommandNames(); +static const auto s_valuesDogCommand = validation::getDogCommandValues(); + +template <> +validation::DogCommand Argument::convert(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid DogCommand value)ex" } }; + } + + const auto result = internal::sorted_map_lookup( + s_valuesDogCommand, + std::string_view { value.get() }); + + if (!result) + { + throw service::schema_exception { { R"ex(not a valid DogCommand value)ex" } }; + } + + return *result; +} + +template <> +service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), std::move(params), + [](validation::DogCommand value, const ResolverParams&) + { + response::Value resolvedResult(response::Type::EnumValue); + + resolvedResult.set(std::string { s_namesDogCommand[static_cast(value)] }); + + return resolvedResult; + }); +} + +template <> +void Result::validateScalar(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid DogCommand value)ex" } }; + } + + const auto [itr, itrEnd] = internal::sorted_map_equal_range( + s_valuesDogCommand.begin(), + s_valuesDogCommand.end(), + std::string_view { value.get() }); + + if (itr == itrEnd) + { + throw service::schema_exception { { R"ex(not a valid DogCommand value)ex" } }; + } +} + +static const auto s_namesCatCommand = validation::getCatCommandNames(); +static const auto s_valuesCatCommand = validation::getCatCommandValues(); + +template <> +validation::CatCommand Argument::convert(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid CatCommand value)ex" } }; + } + + const auto result = internal::sorted_map_lookup( + s_valuesCatCommand, + std::string_view { value.get() }); + + if (!result) + { + throw service::schema_exception { { R"ex(not a valid CatCommand value)ex" } }; + } + + return *result; +} + +template <> +service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), std::move(params), + [](validation::CatCommand value, const ResolverParams&) + { + response::Value resolvedResult(response::Type::EnumValue); + + resolvedResult.set(std::string { s_namesCatCommand[static_cast(value)] }); + + return resolvedResult; + }); +} + +template <> +void Result::validateScalar(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid CatCommand value)ex" } }; + } + + const auto [itr, itrEnd] = internal::sorted_map_equal_range( + s_valuesCatCommand.begin(), + s_valuesCatCommand.end(), + std::string_view { value.get() }); + + if (itr == itrEnd) + { + throw service::schema_exception { { R"ex(not a valid CatCommand value)ex" } }; + } +} + +template <> +validation::ComplexInput Argument::convert(const response::Value& value) +{ + auto valueName = service::ModifiedArgument::require("name", value); + auto valueOwner = service::ModifiedArgument::require("owner", value); + + return validation::ComplexInput { + std::move(valueName), + std::move(valueOwner) + }; +} + +} // namespace service + +namespace validation { + +ComplexInput::ComplexInput() noexcept + : name {} + , owner {} +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ComplexInput::ComplexInput( + std::optional nameArg, + std::optional ownerArg) noexcept + : name { std::move(nameArg) } + , owner { std::move(ownerArg) } +{ +} + +ComplexInput::ComplexInput(const ComplexInput& other) + : name { service::ModifiedArgument::duplicate(other.name) } + , owner { service::ModifiedArgument::duplicate(other.owner) } +{ +} + +ComplexInput::ComplexInput(ComplexInput&& other) noexcept + : name { std::move(other.name) } + , owner { std::move(other.owner) } +{ +} + +ComplexInput::~ComplexInput() +{ + // Explicit definition to prevent ODR violations when LTO is enabled. +} + +ComplexInput& ComplexInput::operator=(const ComplexInput& other) +{ + ComplexInput value { other }; + + std::swap(*this, value); + + return *this; +} + +ComplexInput& ComplexInput::operator=(ComplexInput&& other) noexcept +{ + name = std::move(other.name); + owner = std::move(other.owner); + + return *this; +} + +} // namespace validation +} // namespace graphql diff --git a/samples/validation/schema/validation_schema_files b/samples/validation/schema/validation_schema_files index 60750fdd..f091b606 100644 --- a/samples/validation/schema/validation_schema_files +++ b/samples/validation/schema/validation_schema_files @@ -1,3 +1,4 @@ +ValidationSharedTypes.cpp ValidationSchema.cpp SentientObject.cpp PetObject.cpp diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index f528477d..22eb1360 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -42,9 +42,10 @@ Generator::Generator(SchemaOptions&& schemaOptions, GeneratorOptions&& options) , _sourceDir(getSourceDir()) , _schemaHeaderPath(getSchemaHeaderPath()) , _schemaModulePath(getSchemaModulePath()) + , _schemaSourcePath(getSchemaSourcePath()) , _sharedTypesHeaderPath(getSharedTypesHeaderPath()) , _sharedTypesModulePath(getSharedTypesModulePath()) - , _sourcePath(getSourcePath()) + , _sharedTypesSourcePath(getSharedTypesSourcePath()) { } @@ -88,6 +89,14 @@ std::string Generator::getSchemaModulePath() const noexcept return fullPath.string(); } +std::string Generator::getSchemaSourcePath() const noexcept +{ + std::filesystem::path fullPath { _sourceDir }; + + fullPath /= (std::string { _loader.getFilenamePrefix() } + "Schema.cpp"); + return fullPath.string(); +} + std::string Generator::getSharedTypesHeaderPath() const noexcept { std::filesystem::path fullPath { _headerDir }; @@ -104,11 +113,11 @@ std::string Generator::getSharedTypesModulePath() const noexcept return fullPath.string(); } -std::string Generator::getSourcePath() const noexcept +std::string Generator::getSharedTypesSourcePath() const noexcept { std::filesystem::path fullPath { _sourceDir }; - fullPath /= (std::string { _loader.getFilenamePrefix() } + "Schema.cpp"); + fullPath /= (std::string { _loader.getFilenamePrefix() } + "SharedTypes.cpp"); return fullPath.string(); } @@ -136,9 +145,14 @@ std::vector Generator::Build() const noexcept builtFiles.push_back(_schemaModulePath); } - if (outputSource()) + if (outputSharedTypesSource()) + { + builtFiles.push_back(_sharedTypesSourcePath); + } + + if (outputSchemaSource()) { - builtFiles.push_back(_sourcePath); + builtFiles.push_back(_schemaSourcePath); } auto separateFiles = outputSeparateFiles(); @@ -1569,51 +1583,25 @@ std::string Generator::getResolverDeclaration(const OutputField& outputField) co resolverName); } -bool Generator::outputSource() const noexcept +bool Generator::outputSharedTypesSource() const noexcept { - std::ofstream sourceFile(_sourcePath, std::ios_base::trunc); + if (_loader.getEnumTypes().empty() && _loader.getInputTypes().empty()) + { + return false; + } + + std::ofstream sourceFile(_sharedTypesSourcePath, std::ios_base::trunc); sourceFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. // WARNING! Do not edit this file manually, your changes will be overwritten. -)cpp"; - - if (!_loader.isIntrospection()) - { - if (_loader.getOperationTypes().empty()) - { - // Normally this would be included by each of the operation object headers. - sourceFile << R"cpp(#include ")cpp" << getSchemaHeaderPath() << R"cpp(" -)cpp"; - } - else - { - for (const auto& operation : _loader.getOperationTypes()) - { - sourceFile << R"cpp(#include ")cpp" << operation.cppType << R"cpp(Object.h" -)cpp"; - } - } - - sourceFile << std::endl; - } - - if (_loader.isIntrospection()) - { - sourceFile << R"cpp(#include "graphqlservice/internal/Introspection.h" -)cpp"; - } - else - { - sourceFile << R"cpp(#include "graphqlservice/internal/Schema.h" +#include "graphqlservice/GraphQLService.h" -#include "graphqlservice/introspection/IntrospectionSchema.h" -)cpp"; - } +#include ")cpp" << getSharedTypesHeaderPath() + << R"cpp(" - sourceFile << R"cpp( #include #include #include @@ -1628,43 +1616,41 @@ using namespace std::literals; )cpp"; NamespaceScope graphqlNamespace { sourceFile, "graphql" }; + NamespaceScope serviceNamespace { sourceFile, "service" }; + PendingBlankLine pendingSeparator { sourceFile }; - if (!_loader.getEnumTypes().empty() || !_loader.getInputTypes().empty()) - { - NamespaceScope serviceNamespace { sourceFile, "service" }; - - sourceFile << std::endl; + pendingSeparator.reset(); - for (const auto& enumType : _loader.getEnumTypes()) - { - sourceFile << R"cpp(static const auto s_names)cpp" << enumType.cppType << R"cpp( = )cpp" - << _loader.getSchemaNamespace() << R"cpp(::get)cpp" << enumType.cppType - << R"cpp(Names(); + for (const auto& enumType : _loader.getEnumTypes()) + { + sourceFile << R"cpp(static const auto s_names)cpp" << enumType.cppType << R"cpp( = )cpp" + << _loader.getSchemaNamespace() << R"cpp(::get)cpp" << enumType.cppType + << R"cpp(Names(); static const auto s_values)cpp" - << enumType.cppType << R"cpp( = )cpp" << _loader.getSchemaNamespace() - << R"cpp(::get)cpp" << enumType.cppType << R"cpp(Values(); + << enumType.cppType << R"cpp( = )cpp" << _loader.getSchemaNamespace() + << R"cpp(::get)cpp" << enumType.cppType << R"cpp(Values(); template <> )cpp" << _loader.getSchemaNamespace() - << R"cpp(::)cpp" << enumType.cppType << R"cpp( Argument<)cpp" - << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType - << R"cpp(>::convert(const response::Value& value) + << R"cpp(::)cpp" << enumType.cppType << R"cpp( Argument<)cpp" + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType + << R"cpp(>::convert(const response::Value& value) { if (!value.maybe_enum()) { throw service::schema_exception { { R"ex(not a valid )cpp" - << enumType.type << R"cpp( value)ex" } }; + << enumType.type << R"cpp( value)ex" } }; } const auto result = internal::sorted_map_lookup( - s_values)cpp" << enumType.cppType - << R"cpp(, + s_values)cpp" + << enumType.cppType << R"cpp(, std::string_view { value.get() }); if (!result) { throw service::schema_exception { { R"ex(not a valid )cpp" - << enumType.type << R"cpp( value)ex" } }; + << enumType.type << R"cpp( value)ex" } }; } return *result; @@ -1672,21 +1658,21 @@ template <> template <> service::AwaitableResolver Result<)cpp" - << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType - << R"cpp(>::convert(service::AwaitableScalar<)cpp" - << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType - << R"cpp(> result, ResolverParams&& params) + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType + << R"cpp(>::convert(service::AwaitableScalar<)cpp" + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType + << R"cpp(> result, ResolverParams&& params) { return ModifiedResult<)cpp" - << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType - << R"cpp(>::resolve(std::move(result), std::move(params), + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType + << R"cpp(>::resolve(std::move(result), std::move(params), []()cpp" << _loader.getSchemaNamespace() - << R"cpp(::)cpp" << enumType.cppType << R"cpp( value, const ResolverParams&) + << R"cpp(::)cpp" << enumType.cppType << R"cpp( value, const ResolverParams&) { response::Value resolvedResult(response::Type::EnumValue); resolvedResult.set(std::string { s_names)cpp" - << enumType.cppType << R"cpp([static_cast(value)] }); + << enumType.cppType << R"cpp([static_cast(value)] }); return resolvedResult; }); @@ -1694,274 +1680,277 @@ service::AwaitableResolver Result<)cpp" template <> void Result<)cpp" << _loader.getSchemaNamespace() - << R"cpp(::)cpp" << enumType.cppType - << R"cpp(>::validateScalar(const response::Value& value) + << R"cpp(::)cpp" << enumType.cppType + << R"cpp(>::validateScalar(const response::Value& value) { if (!value.maybe_enum()) { throw service::schema_exception { { R"ex(not a valid )cpp" - << enumType.type << R"cpp( value)ex" } }; + << enumType.type << R"cpp( value)ex" } }; } const auto [itr, itrEnd] = internal::sorted_map_equal_range( - s_values)cpp" << enumType.cppType - << R"cpp(.begin(), - s_values)cpp" << enumType.cppType - << R"cpp(.end(), + s_values)cpp" + << enumType.cppType << R"cpp(.begin(), + s_values)cpp" + << enumType.cppType << R"cpp(.end(), std::string_view { value.get() }); if (itr == itrEnd) { throw service::schema_exception { { R"ex(not a valid )cpp" - << enumType.type << R"cpp( value)ex" } }; + << enumType.type << R"cpp( value)ex" } }; } } )cpp"; - } + } - for (const auto& inputType : _loader.getInputTypes()) - { - bool firstField = true; + for (const auto& inputType : _loader.getInputTypes()) + { + bool firstField = true; - sourceFile << R"cpp(template <> + sourceFile << R"cpp(template <> )cpp" << _loader.getSchemaNamespace() - << R"cpp(::)cpp" << inputType.cppType << R"cpp( Argument<)cpp" - << _loader.getSchemaNamespace() << R"cpp(::)cpp" << inputType.cppType - << R"cpp(>::convert(const response::Value& value) + << R"cpp(::)cpp" << inputType.cppType << R"cpp( Argument<)cpp" + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << inputType.cppType + << R"cpp(>::convert(const response::Value& value) { )cpp"; - for (const auto& inputField : inputType.fields) + for (const auto& inputField : inputType.fields) + { + if (inputField.defaultValue.type() != response::Type::Null) { - if (inputField.defaultValue.type() != response::Type::Null) + if (firstField) { - if (firstField) - { - firstField = false; - sourceFile << R"cpp( const auto defaultValue = []() + firstField = false; + sourceFile << R"cpp( const auto defaultValue = []() { response::Value values(response::Type::Map); response::Value entry; )cpp"; - } + } - sourceFile << getArgumentDefaultValue(0, inputField.defaultValue) - << R"cpp( values.emplace_back(")cpp" << inputField.name - << R"cpp(", std::move(entry)); + sourceFile << getArgumentDefaultValue(0, inputField.defaultValue) + << R"cpp( values.emplace_back(")cpp" << inputField.name + << R"cpp(", std::move(entry)); )cpp"; - } } + } - if (!firstField) - { - sourceFile << R"cpp( + if (!firstField) + { + sourceFile << R"cpp( return values; }(); )cpp"; - } + } - for (const auto& inputField : inputType.fields) - { - sourceFile << getArgumentDeclaration(inputField, "value", "value", "defaultValue"); - } + for (const auto& inputField : inputType.fields) + { + sourceFile << getArgumentDeclaration(inputField, "value", "value", "defaultValue"); + } - if (!inputType.fields.empty()) - { - sourceFile << std::endl; - } + if (!inputType.fields.empty()) + { + sourceFile << std::endl; + } - sourceFile << R"cpp( return )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" - << inputType.cppType << R"cpp( { + sourceFile << R"cpp( return )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" + << inputType.cppType << R"cpp( { )cpp"; - firstField = true; + firstField = true; - for (const auto& inputField : inputType.fields) - { - std::string fieldName(inputField.cppName); + for (const auto& inputField : inputType.fields) + { + std::string fieldName(inputField.cppName); - if (!firstField) - { - sourceFile << R"cpp(, + if (!firstField) + { + sourceFile << R"cpp(, )cpp"; - } + } - const bool shouldMove = SchemaLoader::shouldMoveInputField(inputField); + const bool shouldMove = SchemaLoader::shouldMoveInputField(inputField); - firstField = false; - fieldName[0] = - static_cast(std::toupper(static_cast(fieldName[0]))); + firstField = false; + fieldName[0] = + static_cast(std::toupper(static_cast(fieldName[0]))); - sourceFile << R"cpp( )cpp"; + sourceFile << R"cpp( )cpp"; - if (shouldMove) - { - sourceFile << R"cpp(std::move()cpp"; - } + if (shouldMove) + { + sourceFile << R"cpp(std::move()cpp"; + } - sourceFile << R"cpp(value)cpp" << fieldName; + sourceFile << R"cpp(value)cpp" << fieldName; - if (shouldMove) - { - sourceFile << R"cpp())cpp"; - } + if (shouldMove) + { + sourceFile << R"cpp())cpp"; } + } - sourceFile << R"cpp( + sourceFile << R"cpp( }; } )cpp"; - } - - serviceNamespace.exit(); - sourceFile << std::endl; } - NamespaceScope schemaNamespace { sourceFile, _loader.getSchemaNamespace() }; + serviceNamespace.exit(); + pendingSeparator.add(); - for (const auto& inputType : _loader.getInputTypes()) + if (!_loader.getInputTypes().empty()) { - sourceFile << std::endl - << inputType.cppType << R"cpp(::)cpp" << inputType.cppType - << R"cpp(() noexcept)cpp"; + pendingSeparator.reset(); - bool firstField = true; + NamespaceScope schemaNamespace { sourceFile, _loader.getSchemaNamespace() }; - for (const auto& inputField : inputType.fields) + for (const auto& inputType : _loader.getInputTypes()) { - sourceFile << R"cpp( + sourceFile << std::endl + << inputType.cppType << R"cpp(::)cpp" << inputType.cppType + << R"cpp(() noexcept)cpp"; + + bool firstField = true; + + for (const auto& inputField : inputType.fields) + { + sourceFile << R"cpp( )cpp" << (firstField ? R"cpp(:)cpp" : R"cpp(,)cpp") - << R"cpp( )cpp" << inputField.cppName << R"cpp( {})cpp"; - firstField = false; - } + << R"cpp( )cpp" << inputField.cppName << R"cpp( {})cpp"; + firstField = false; + } - sourceFile << R"cpp( + sourceFile << R"cpp( { // Explicit definition to prevent ODR violations when LTO is enabled. } )cpp" << inputType.cppType - << R"cpp(::)cpp" << inputType.cppType << R"cpp(()cpp"; + << R"cpp(::)cpp" << inputType.cppType << R"cpp(()cpp"; - firstField = true; + firstField = true; - for (const auto& inputField : inputType.fields) - { - if (!firstField) + for (const auto& inputField : inputType.fields) { - sourceFile << R"cpp(,)cpp"; - } + if (!firstField) + { + sourceFile << R"cpp(,)cpp"; + } - firstField = false; - sourceFile << R"cpp( + firstField = false; + sourceFile << R"cpp( )cpp" << _loader.getInputCppType(inputField) - << R"cpp( )cpp" << inputField.cppName << R"cpp(Arg)cpp"; - } + << R"cpp( )cpp" << inputField.cppName << R"cpp(Arg)cpp"; + } - sourceFile << R"cpp() noexcept + sourceFile << R"cpp() noexcept )cpp"; - firstField = true; + firstField = true; - for (const auto& inputField : inputType.fields) - { - sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); - firstField = false; + for (const auto& inputField : inputType.fields) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; - sourceFile << inputField.cppName << R"cpp( { std::move()cpp" << inputField.cppName - << R"cpp(Arg) } + sourceFile << inputField.cppName << R"cpp( { std::move()cpp" << inputField.cppName + << R"cpp(Arg) } )cpp"; - } + } - sourceFile << R"cpp({ + sourceFile << R"cpp({ } )cpp" << inputType.cppType - << R"cpp(::)cpp" << inputType.cppType << R"cpp((const )cpp" << inputType.cppType - << R"cpp(& other) + << R"cpp(::)cpp" << inputType.cppType << R"cpp((const )cpp" + << inputType.cppType << R"cpp(& other) )cpp"; - firstField = true; - - for (const auto& inputField : inputType.fields) - { - sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); - firstField = false; - - sourceFile << inputField.cppName << R"cpp( { service::ModifiedArgument<)cpp" - << _loader.getCppType(inputField.type) << R"cpp(>::duplicate)cpp"; + firstField = true; - if (!inputField.modifiers.empty()) + for (const auto& inputField : inputType.fields) { - bool firstModifier = true; + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; + + sourceFile << inputField.cppName << R"cpp( { service::ModifiedArgument<)cpp" + << _loader.getCppType(inputField.type) << R"cpp(>::duplicate)cpp"; - for (const auto modifier : inputField.modifiers) + if (!inputField.modifiers.empty()) { - sourceFile << (firstModifier ? R"cpp(<)cpp" : R"cpp(, )cpp"); - firstModifier = false; + bool firstModifier = true; - switch (modifier) + for (const auto modifier : inputField.modifiers) { - case service::TypeModifier::None: - sourceFile << R"cpp(service::TypeModifier::None)cpp"; - break; + sourceFile << (firstModifier ? R"cpp(<)cpp" : R"cpp(, )cpp"); + firstModifier = false; + + switch (modifier) + { + case service::TypeModifier::None: + sourceFile << R"cpp(service::TypeModifier::None)cpp"; + break; - case service::TypeModifier::Nullable: - sourceFile << R"cpp(service::TypeModifier::Nullable)cpp"; - break; + case service::TypeModifier::Nullable: + sourceFile << R"cpp(service::TypeModifier::Nullable)cpp"; + break; - case service::TypeModifier::List: - sourceFile << R"cpp(service::TypeModifier::List)cpp"; - break; + case service::TypeModifier::List: + sourceFile << R"cpp(service::TypeModifier::List)cpp"; + break; + } } - } - sourceFile << R"cpp(>)cpp"; - } + sourceFile << R"cpp(>)cpp"; + } - sourceFile << R"cpp((other.)cpp" << inputField.cppName << R"cpp() } + sourceFile << R"cpp((other.)cpp" << inputField.cppName << R"cpp() } )cpp"; - } + } - sourceFile << R"cpp({ + sourceFile << R"cpp({ } )cpp" << inputType.cppType - << R"cpp(::)cpp" << inputType.cppType << R"cpp(()cpp" << inputType.cppType - << R"cpp(&& other) noexcept + << R"cpp(::)cpp" << inputType.cppType << R"cpp(()cpp" << inputType.cppType + << R"cpp(&& other) noexcept )cpp"; - firstField = true; + firstField = true; - for (const auto& inputField : inputType.fields) - { - sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); - firstField = false; + for (const auto& inputField : inputType.fields) + { + sourceFile << (firstField ? R"cpp( : )cpp" : R"cpp( , )cpp"); + firstField = false; - sourceFile << inputField.cppName << R"cpp( { std::move(other.)cpp" << inputField.cppName - << R"cpp() } + sourceFile << inputField.cppName << R"cpp( { std::move(other.)cpp" + << inputField.cppName << R"cpp() } )cpp"; - } + } - sourceFile << R"cpp({ + sourceFile << R"cpp({ } )cpp" << inputType.cppType - << R"cpp(::~)cpp" << inputType.cppType << R"cpp(() + << R"cpp(::~)cpp" << inputType.cppType << R"cpp(() { // Explicit definition to prevent ODR violations when LTO is enabled. } )cpp" << inputType.cppType - << R"cpp(& )cpp" << inputType.cppType << R"cpp(::operator=(const )cpp" - << inputType.cppType << R"cpp(& other) + << R"cpp(& )cpp" << inputType.cppType << R"cpp(::operator=(const )cpp" + << inputType.cppType << R"cpp(& other) { )cpp" << inputType.cppType - << R"cpp( value { other }; + << R"cpp( value { other }; std::swap(*this, value); @@ -1969,24 +1958,90 @@ void Result<)cpp" << _loader.getSchemaNamespace() } )cpp" << inputType.cppType - << R"cpp(& )cpp" << inputType.cppType << R"cpp(::operator=()cpp" - << inputType.cppType << R"cpp(&& other) noexcept + << R"cpp(& )cpp" << inputType.cppType << R"cpp(::operator=()cpp" + << inputType.cppType << R"cpp(&& other) noexcept { )cpp"; - for (const auto& inputField : inputType.fields) - { - sourceFile << R"cpp( )cpp" << inputField.cppName << R"cpp( = std::move(other.)cpp" - << inputField.cppName << R"cpp(); + for (const auto& inputField : inputType.fields) + { + sourceFile << R"cpp( )cpp" << inputField.cppName + << R"cpp( = std::move(other.)cpp" << inputField.cppName << R"cpp(); )cpp"; - } + } - sourceFile << R"cpp( + sourceFile << R"cpp( return *this; } + )cpp"; + } } + return true; +} + +bool Generator::outputSchemaSource() const noexcept +{ + std::ofstream sourceFile(_schemaSourcePath, std::ios_base::trunc); + + sourceFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +)cpp"; + + if (!_loader.isIntrospection()) + { + if (_loader.getOperationTypes().empty()) + { + // Normally this would be included by each of the operation object headers. + sourceFile << R"cpp(#include ")cpp" << getSchemaHeaderPath() << R"cpp(" +)cpp"; + } + else + { + for (const auto& operation : _loader.getOperationTypes()) + { + sourceFile << R"cpp(#include ")cpp" << operation.cppType << R"cpp(Object.h" +)cpp"; + } + } + + sourceFile << std::endl; + } + + if (_loader.isIntrospection()) + { + sourceFile << R"cpp(#include "graphqlservice/internal/Introspection.h" +)cpp"; + } + else + { + sourceFile << R"cpp(#include "graphqlservice/internal/Schema.h" + +#include "graphqlservice/introspection/IntrospectionSchema.h" +)cpp"; + } + + sourceFile << R"cpp( +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +)cpp"; + + const auto schemaNamespace = std::format(R"cpp(graphql::{})cpp", _loader.getSchemaNamespace()); + NamespaceScope schemaNamespaceScope { sourceFile, schemaNamespace }; + if (!_loader.isIntrospection()) { bool firstOperation = true; @@ -2220,7 +2275,12 @@ Operations::Operations()cpp"; { bool firstValue = true; - sourceFile << R"cpp( type)cpp" << enumType.cppType << R"cpp(->AddEnumValues({ + sourceFile << R"cpp( + static const auto s_names)cpp" + << enumType.cppType << R"cpp( = get)cpp" << enumType.cppType + << R"cpp(Names(); + type)cpp" << enumType.cppType + << R"cpp(->AddEnumValues({ )cpp"; for (const auto& enumValue : enumType.values) @@ -2232,7 +2292,7 @@ Operations::Operations()cpp"; } firstValue = false; - sourceFile << R"cpp( { service::s_names)cpp" << enumType.cppType + sourceFile << R"cpp( { s_names)cpp" << enumType.cppType << R"cpp([static_cast()cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType << R"cpp(::)cpp" << enumValue.cppValue << R"cpp()], R"md()cpp"; diff --git a/src/introspection/IntrospectionSchema.cpp b/src/introspection/IntrospectionSchema.cpp index f735c21d..44b76262 100644 --- a/src/introspection/IntrospectionSchema.cpp +++ b/src/introspection/IntrospectionSchema.cpp @@ -16,124 +16,7 @@ using namespace std::literals; -namespace graphql { -namespace service { - -static const auto s_namesTypeKind = introspection::getTypeKindNames(); -static const auto s_valuesTypeKind = introspection::getTypeKindValues(); - -template <> -introspection::TypeKind Argument::convert(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid __TypeKind value)ex" } }; - } - - const auto result = internal::sorted_map_lookup( - s_valuesTypeKind, - std::string_view { value.get() }); - - if (!result) - { - throw service::schema_exception { { R"ex(not a valid __TypeKind value)ex" } }; - } - - return *result; -} - -template <> -service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) -{ - return ModifiedResult::resolve(std::move(result), std::move(params), - [](introspection::TypeKind value, const ResolverParams&) - { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesTypeKind[static_cast(value)] }); - - return resolvedResult; - }); -} - -template <> -void Result::validateScalar(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid __TypeKind value)ex" } }; - } - - const auto [itr, itrEnd] = internal::sorted_map_equal_range( - s_valuesTypeKind.begin(), - s_valuesTypeKind.end(), - std::string_view { value.get() }); - - if (itr == itrEnd) - { - throw service::schema_exception { { R"ex(not a valid __TypeKind value)ex" } }; - } -} - -static const auto s_namesDirectiveLocation = introspection::getDirectiveLocationNames(); -static const auto s_valuesDirectiveLocation = introspection::getDirectiveLocationValues(); - -template <> -introspection::DirectiveLocation Argument::convert(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid __DirectiveLocation value)ex" } }; - } - - const auto result = internal::sorted_map_lookup( - s_valuesDirectiveLocation, - std::string_view { value.get() }); - - if (!result) - { - throw service::schema_exception { { R"ex(not a valid __DirectiveLocation value)ex" } }; - } - - return *result; -} - -template <> -service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) -{ - return ModifiedResult::resolve(std::move(result), std::move(params), - [](introspection::DirectiveLocation value, const ResolverParams&) - { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesDirectiveLocation[static_cast(value)] }); - - return resolvedResult; - }); -} - -template <> -void Result::validateScalar(const response::Value& value) -{ - if (!value.maybe_enum()) - { - throw service::schema_exception { { R"ex(not a valid __DirectiveLocation value)ex" } }; - } - - const auto [itr, itrEnd] = internal::sorted_map_equal_range( - s_valuesDirectiveLocation.begin(), - s_valuesDirectiveLocation.end(), - std::string_view { value.get() }); - - if (itr == itrEnd) - { - throw service::schema_exception { { R"ex(not a valid __DirectiveLocation value)ex" } }; - } -} - -} // namespace service - -namespace introspection { +namespace graphql::introspection { void AddTypesToSchema(const std::shared_ptr& schema) { @@ -159,36 +42,40 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeDirective = schema::ObjectType::Make(R"gql(__Directive)gql"sv, R"md()md"sv); schema->AddType(R"gql(__Directive)gql"sv, typeDirective); + + static const auto s_namesTypeKind = getTypeKindNames(); typeTypeKind->AddEnumValues({ - { service::s_namesTypeKind[static_cast(introspection::TypeKind::SCALAR)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::INTERFACE)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::UNION)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::ENUM)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::LIST)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::NON_NULL)], R"md()md"sv, std::nullopt } + { s_namesTypeKind[static_cast(introspection::TypeKind::SCALAR)], R"md()md"sv, std::nullopt }, + { s_namesTypeKind[static_cast(introspection::TypeKind::OBJECT)], R"md()md"sv, std::nullopt }, + { s_namesTypeKind[static_cast(introspection::TypeKind::INTERFACE)], R"md()md"sv, std::nullopt }, + { s_namesTypeKind[static_cast(introspection::TypeKind::UNION)], R"md()md"sv, std::nullopt }, + { s_namesTypeKind[static_cast(introspection::TypeKind::ENUM)], R"md()md"sv, std::nullopt }, + { s_namesTypeKind[static_cast(introspection::TypeKind::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, + { s_namesTypeKind[static_cast(introspection::TypeKind::LIST)], R"md()md"sv, std::nullopt }, + { s_namesTypeKind[static_cast(introspection::TypeKind::NON_NULL)], R"md()md"sv, std::nullopt } }); + + static const auto s_namesDirectiveLocation = getDirectiveLocationNames(); typeDirectiveLocation->AddEnumValues({ - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::QUERY)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::MUTATION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SUBSCRIPTION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_SPREAD)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INLINE_FRAGMENT)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::VARIABLE_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCHEMA)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCALAR)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ARGUMENT_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INTERFACE)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::UNION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM_VALUE)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_FIELD_DEFINITION)], R"md()md"sv, std::nullopt } + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::QUERY)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::MUTATION)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SUBSCRIPTION)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_DEFINITION)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_SPREAD)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INLINE_FRAGMENT)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::VARIABLE_DEFINITION)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCHEMA)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCALAR)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::OBJECT)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD_DEFINITION)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ARGUMENT_DEFINITION)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INTERFACE)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::UNION)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM_VALUE)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, + { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_FIELD_DEFINITION)], R"md()md"sv, std::nullopt } }); AddSchemaDetails(typeSchema, schema); @@ -225,5 +112,4 @@ void AddTypesToSchema(const std::shared_ptr& schema) }, false)); } -} // namespace introspection -} // namespace graphql +} // namespace graphql::introspection diff --git a/src/introspection/IntrospectionSharedTypes.cpp b/src/introspection/IntrospectionSharedTypes.cpp new file mode 100644 index 00000000..5b1892fe --- /dev/null +++ b/src/introspection/IntrospectionSharedTypes.cpp @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#include "graphqlservice/GraphQLService.h" + +#include "IntrospectionSharedTypes.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace graphql { +namespace service { + +static const auto s_namesTypeKind = introspection::getTypeKindNames(); +static const auto s_valuesTypeKind = introspection::getTypeKindValues(); + +template <> +introspection::TypeKind Argument::convert(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid __TypeKind value)ex" } }; + } + + const auto result = internal::sorted_map_lookup( + s_valuesTypeKind, + std::string_view { value.get() }); + + if (!result) + { + throw service::schema_exception { { R"ex(not a valid __TypeKind value)ex" } }; + } + + return *result; +} + +template <> +service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), std::move(params), + [](introspection::TypeKind value, const ResolverParams&) + { + response::Value resolvedResult(response::Type::EnumValue); + + resolvedResult.set(std::string { s_namesTypeKind[static_cast(value)] }); + + return resolvedResult; + }); +} + +template <> +void Result::validateScalar(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid __TypeKind value)ex" } }; + } + + const auto [itr, itrEnd] = internal::sorted_map_equal_range( + s_valuesTypeKind.begin(), + s_valuesTypeKind.end(), + std::string_view { value.get() }); + + if (itr == itrEnd) + { + throw service::schema_exception { { R"ex(not a valid __TypeKind value)ex" } }; + } +} + +static const auto s_namesDirectiveLocation = introspection::getDirectiveLocationNames(); +static const auto s_valuesDirectiveLocation = introspection::getDirectiveLocationValues(); + +template <> +introspection::DirectiveLocation Argument::convert(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid __DirectiveLocation value)ex" } }; + } + + const auto result = internal::sorted_map_lookup( + s_valuesDirectiveLocation, + std::string_view { value.get() }); + + if (!result) + { + throw service::schema_exception { { R"ex(not a valid __DirectiveLocation value)ex" } }; + } + + return *result; +} + +template <> +service::AwaitableResolver Result::convert(service::AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), std::move(params), + [](introspection::DirectiveLocation value, const ResolverParams&) + { + response::Value resolvedResult(response::Type::EnumValue); + + resolvedResult.set(std::string { s_namesDirectiveLocation[static_cast(value)] }); + + return resolvedResult; + }); +} + +template <> +void Result::validateScalar(const response::Value& value) +{ + if (!value.maybe_enum()) + { + throw service::schema_exception { { R"ex(not a valid __DirectiveLocation value)ex" } }; + } + + const auto [itr, itrEnd] = internal::sorted_map_equal_range( + s_valuesDirectiveLocation.begin(), + s_valuesDirectiveLocation.end(), + std::string_view { value.get() }); + + if (itr == itrEnd) + { + throw service::schema_exception { { R"ex(not a valid __DirectiveLocation value)ex" } }; + } +} + +} // namespace service +} // namespace graphql diff --git a/src/introspection/introspection_schema_files b/src/introspection/introspection_schema_files index fba57600..fac4e1ee 100644 --- a/src/introspection/introspection_schema_files +++ b/src/introspection/introspection_schema_files @@ -1,3 +1,4 @@ +IntrospectionSharedTypes.cpp IntrospectionSchema.cpp SchemaObject.cpp TypeObject.cpp From e1e5f1fdaf74ee46a52dd0647726d20e1c5235e8 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 24 Sep 2024 09:40:01 -0700 Subject: [PATCH 082/123] fix: include SharedTypes.h in clients --- samples/client/benchmark/TodayClient.h | 2 +- samples/proxy/query/ProxyClient.h | 2 +- src/ClientGenerator.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/client/benchmark/TodayClient.h b/samples/client/benchmark/TodayClient.h index d0f74413..453685fe 100644 --- a/samples/client/benchmark/TodayClient.h +++ b/samples/client/benchmark/TodayClient.h @@ -14,7 +14,7 @@ #include "graphqlservice/internal/Version.h" -#include "TodaySchema.h" +#include "TodaySharedTypes.h" #include #include diff --git a/samples/proxy/query/ProxyClient.h b/samples/proxy/query/ProxyClient.h index f541794f..58669b8f 100644 --- a/samples/proxy/query/ProxyClient.h +++ b/samples/proxy/query/ProxyClient.h @@ -14,7 +14,7 @@ #include "graphqlservice/internal/Version.h" -#include "ProxySchema.h" +#include "ProxySharedTypes.h" #include #include diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 69ba95ba..3b37757e 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -198,7 +198,7 @@ bool Generator::outputHeader() const noexcept { headerFile << R"cpp( #include ")cpp" << _schemaLoader.getFilenamePrefix() - << R"cpp(Schema.h" + << R"cpp(SharedTypes.h" )cpp"; } @@ -1640,7 +1640,7 @@ int main(int argc, char** argv) po::bool_switch(&noIntrospection), "Do not expect support for Introspection")("shared-types", po::bool_switch(&sharedTypes), - "Re-use shared types from Schema.h"); + "Re-use shared types from SharedTypes.h"); positional.add("schema", 1).add("request", 1).add("prefix", 1).add("namespace", 1); try From 68b9d33d85d3b77937b0ef09e02ced251ab6aac4 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 24 Sep 2024 09:46:34 -0700 Subject: [PATCH 083/123] fix: cleanup extra blank lines --- samples/learn/schema/StarWarsSchema.cpp | 1 - samples/proxy/schema/ProxySchema.cpp | 1 - samples/today/nointrospection/TodaySchema.cpp | 1 - samples/today/schema/TodaySchema.cpp | 1 - samples/validation/schema/ValidationSchema.cpp | 2 -- src/SchemaGenerator.cpp | 3 +-- src/introspection/IntrospectionSchema.cpp | 2 -- 7 files changed, 1 insertion(+), 10 deletions(-) diff --git a/samples/learn/schema/StarWarsSchema.cpp b/samples/learn/schema/StarWarsSchema.cpp index 3813cab7..6e093b32 100644 --- a/samples/learn/schema/StarWarsSchema.cpp +++ b/samples/learn/schema/StarWarsSchema.cpp @@ -57,7 +57,6 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeSubscription = schema::ObjectType::Make(R"gql(Subscription)gql"sv, R"md()md"sv); schema->AddType(R"gql(Subscription)gql"sv, typeSubscription); - static const auto s_namesEpisode = getEpisodeNames(); typeEpisode->AddEnumValues({ { s_namesEpisode[static_cast(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt }, diff --git a/samples/proxy/schema/ProxySchema.cpp b/samples/proxy/schema/ProxySchema.cpp index 6be2146e..5bb1337b 100644 --- a/samples/proxy/schema/ProxySchema.cpp +++ b/samples/proxy/schema/ProxySchema.cpp @@ -41,7 +41,6 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeQueryResults = schema::ObjectType::Make(R"gql(QueryResults)gql"sv, R"md()md"sv); schema->AddType(R"gql(QueryResults)gql"sv, typeQueryResults); - static const auto s_namesOperationType = getOperationTypeNames(); typeOperationType->AddEnumValues({ { s_namesOperationType[static_cast(proxy::OperationType::QUERY)], R"md()md"sv, std::nullopt }, diff --git a/samples/today/nointrospection/TodaySchema.cpp b/samples/today/nointrospection/TodaySchema.cpp index 106258d5..98cf8f6d 100644 --- a/samples/today/nointrospection/TodaySchema.cpp +++ b/samples/today/nointrospection/TodaySchema.cpp @@ -97,7 +97,6 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeExpensive = schema::ObjectType::Make(R"gql(Expensive)gql"sv, R"md()md"sv); schema->AddType(R"gql(Expensive)gql"sv, typeExpensive); - static const auto s_namesTaskState = getTaskStateNames(); typeTaskState->AddEnumValues({ { s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, diff --git a/samples/today/schema/TodaySchema.cpp b/samples/today/schema/TodaySchema.cpp index b2395a64..7436b7fa 100644 --- a/samples/today/schema/TodaySchema.cpp +++ b/samples/today/schema/TodaySchema.cpp @@ -100,7 +100,6 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeExpensive = schema::ObjectType::Make(R"gql(Expensive)gql"sv, R"md()md"sv); schema->AddType(R"gql(Expensive)gql"sv, typeExpensive); - static const auto s_namesTaskState = getTaskStateNames(); typeTaskState->AddEnumValues({ { s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, diff --git a/samples/validation/schema/ValidationSchema.cpp b/samples/validation/schema/ValidationSchema.cpp index 463eccda..4a99aec5 100644 --- a/samples/validation/schema/ValidationSchema.cpp +++ b/samples/validation/schema/ValidationSchema.cpp @@ -79,14 +79,12 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeArguments = schema::ObjectType::Make(R"gql(Arguments)gql"sv, R"md()md"sv); schema->AddType(R"gql(Arguments)gql"sv, typeArguments); - static const auto s_namesDogCommand = getDogCommandNames(); typeDogCommand->AddEnumValues({ { s_namesDogCommand[static_cast(validation::DogCommand::SIT)], R"md()md"sv, std::nullopt }, { s_namesDogCommand[static_cast(validation::DogCommand::DOWN)], R"md()md"sv, std::nullopt }, { s_namesDogCommand[static_cast(validation::DogCommand::HEEL)], R"md()md"sv, std::nullopt } }); - static const auto s_namesCatCommand = getCatCommandNames(); typeCatCommand->AddEnumValues({ { s_namesCatCommand[static_cast(validation::CatCommand::JUMP)], R"md()md"sv, std::nullopt } diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 22eb1360..ccf5b518 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -2275,8 +2275,7 @@ Operations::Operations()cpp"; { bool firstValue = true; - sourceFile << R"cpp( - static const auto s_names)cpp" + sourceFile << R"cpp( static const auto s_names)cpp" << enumType.cppType << R"cpp( = get)cpp" << enumType.cppType << R"cpp(Names(); type)cpp" << enumType.cppType diff --git a/src/introspection/IntrospectionSchema.cpp b/src/introspection/IntrospectionSchema.cpp index 44b76262..5bc857ed 100644 --- a/src/introspection/IntrospectionSchema.cpp +++ b/src/introspection/IntrospectionSchema.cpp @@ -42,7 +42,6 @@ void AddTypesToSchema(const std::shared_ptr& schema) auto typeDirective = schema::ObjectType::Make(R"gql(__Directive)gql"sv, R"md()md"sv); schema->AddType(R"gql(__Directive)gql"sv, typeDirective); - static const auto s_namesTypeKind = getTypeKindNames(); typeTypeKind->AddEnumValues({ { s_namesTypeKind[static_cast(introspection::TypeKind::SCALAR)], R"md()md"sv, std::nullopt }, @@ -54,7 +53,6 @@ void AddTypesToSchema(const std::shared_ptr& schema) { s_namesTypeKind[static_cast(introspection::TypeKind::LIST)], R"md()md"sv, std::nullopt }, { s_namesTypeKind[static_cast(introspection::TypeKind::NON_NULL)], R"md()md"sv, std::nullopt } }); - static const auto s_namesDirectiveLocation = getDirectiveLocationNames(); typeDirectiveLocation->AddEnumValues({ { s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::QUERY)], R"md()md"sv, std::nullopt }, From 2dc6ebe0a10b8bdf2da5e2c59f2fb066014ea53d Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 24 Sep 2024 10:54:15 -0700 Subject: [PATCH 084/123] fix(dll): move introspection DLL exports to shared types header --- .../introspection/IntrospectionSchema.h | 33 +--- .../introspection/IntrospectionSharedTypes.h | 33 +++- samples/learn/schema/StarWarsSchema.h | 6 +- samples/learn/schema/StarWarsSharedTypes.h | 6 +- samples/proxy/schema/ProxySchema.h | 6 +- samples/proxy/schema/ProxySharedTypes.h | 6 +- samples/today/nointrospection/TodaySchema.h | 6 +- .../today/nointrospection/TodaySharedTypes.h | 6 +- samples/today/schema/TodaySchema.h | 6 +- samples/today/schema/TodaySharedTypes.h | 6 +- samples/validation/schema/ValidationSchema.h | 6 +- .../validation/schema/ValidationSharedTypes.h | 6 +- src/SchemaGenerator.cpp | 141 ++++++++++-------- src/introspection/IntrospectionSchema.h | 33 +--- src/introspection/IntrospectionSharedTypes.h | 33 +++- 15 files changed, 176 insertions(+), 157 deletions(-) diff --git a/include/graphqlservice/introspection/IntrospectionSchema.h b/include/graphqlservice/introspection/IntrospectionSchema.h index 3ea811b0..b39fe13f 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.h +++ b/include/graphqlservice/introspection/IntrospectionSchema.h @@ -11,6 +11,7 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/DllExports.h" #include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" @@ -25,8 +26,7 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql { -namespace introspection { +namespace graphql::introspection { class Schema; class Type; class Field; @@ -54,33 +54,6 @@ void AddDirectiveDetails(const std::shared_ptr& typeDirectiv GRAPHQLSERVICE_EXPORT void AddTypesToSchema(const std::shared_ptr& schema); -} // namespace introspection - -namespace service { - -#ifdef GRAPHQL_DLLEXPORTS -// Export all of the built-in converters -template <> -GRAPHQLSERVICE_EXPORT introspection::TypeKind Argument::convert( - const response::Value& value); -template <> -GRAPHQLSERVICE_EXPORT AwaitableResolver Result::convert( - AwaitableScalar result, ResolverParams&& params); -template <> -GRAPHQLSERVICE_EXPORT void Result::validateScalar( - const response::Value& value); -template <> -GRAPHQLSERVICE_EXPORT introspection::DirectiveLocation Argument::convert( - const response::Value& value); -template <> -GRAPHQLSERVICE_EXPORT AwaitableResolver Result::convert( - AwaitableScalar result, ResolverParams&& params); -template <> -GRAPHQLSERVICE_EXPORT void Result::validateScalar( - const response::Value& value); -#endif // GRAPHQL_DLLEXPORTS - -} // namespace service -} // namespace graphql +} // namespace graphql::introspection #endif // INTROSPECTIONSCHEMA_H diff --git a/include/graphqlservice/introspection/IntrospectionSharedTypes.h b/include/graphqlservice/introspection/IntrospectionSharedTypes.h index 63b71c2c..9e1d5acb 100644 --- a/include/graphqlservice/introspection/IntrospectionSharedTypes.h +++ b/include/graphqlservice/introspection/IntrospectionSharedTypes.h @@ -10,6 +10,7 @@ #include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/internal/DllExports.h" #include "graphqlservice/internal/Version.h" #include @@ -23,7 +24,8 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql::introspection { +namespace graphql { +namespace introspection { enum class TypeKind { @@ -146,6 +148,33 @@ enum class DirectiveLocation }; } -} // namespace graphql::introspection +} // namespace introspection + +namespace service { + +#ifdef GRAPHQL_DLLEXPORTS +// Export all of the built-in converters +template <> +GRAPHQLSERVICE_EXPORT introspection::TypeKind Argument::convert( + const response::Value& value); +template <> +GRAPHQLSERVICE_EXPORT AwaitableResolver Result::convert( + AwaitableScalar result, ResolverParams&& params); +template <> +GRAPHQLSERVICE_EXPORT void Result::validateScalar( + const response::Value& value); +template <> +GRAPHQLSERVICE_EXPORT introspection::DirectiveLocation Argument::convert( + const response::Value& value); +template <> +GRAPHQLSERVICE_EXPORT AwaitableResolver Result::convert( + AwaitableScalar result, ResolverParams&& params); +template <> +GRAPHQLSERVICE_EXPORT void Result::validateScalar( + const response::Value& value); +#endif // GRAPHQL_DLLEXPORTS + +} // namespace service +} // namespace graphql #endif // INTROSPECTIONSHAREDTYPES_H diff --git a/samples/learn/schema/StarWarsSchema.h b/samples/learn/schema/StarWarsSchema.h index 5182070f..9529c7ec 100644 --- a/samples/learn/schema/StarWarsSchema.h +++ b/samples/learn/schema/StarWarsSchema.h @@ -25,8 +25,7 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql { -namespace learn { +namespace graphql::learn { namespace object { class Character; @@ -73,7 +72,6 @@ void AddSubscriptionDetails(const std::shared_ptr& typeSubsc std::shared_ptr GetSchema(); -} // namespace learn -} // namespace graphql +} // namespace graphql::learn #endif // STARWARSSCHEMA_H diff --git a/samples/learn/schema/StarWarsSharedTypes.h b/samples/learn/schema/StarWarsSharedTypes.h index 007c2b19..b9dee9da 100644 --- a/samples/learn/schema/StarWarsSharedTypes.h +++ b/samples/learn/schema/StarWarsSharedTypes.h @@ -23,7 +23,8 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql::learn { +namespace graphql { +namespace learn { enum class [[nodiscard("unnecessary conversion")]] Episode { @@ -71,6 +72,7 @@ struct [[nodiscard("unnecessary construction")]] ReviewInput std::optional commentary; }; -} // namespace graphql::learn +} // namespace learn +} // namespace graphql #endif // STARWARSSHAREDTYPES_H diff --git a/samples/proxy/schema/ProxySchema.h b/samples/proxy/schema/ProxySchema.h index 1fd0922f..bbaa0e6c 100644 --- a/samples/proxy/schema/ProxySchema.h +++ b/samples/proxy/schema/ProxySchema.h @@ -25,8 +25,7 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql { -namespace proxy { +namespace graphql::proxy { namespace object { class Query; @@ -57,7 +56,6 @@ void AddQueryResultsDetails(const std::shared_ptr& typeQuery std::shared_ptr GetSchema(); -} // namespace proxy -} // namespace graphql +} // namespace graphql::proxy #endif // PROXYSCHEMA_H diff --git a/samples/proxy/schema/ProxySharedTypes.h b/samples/proxy/schema/ProxySharedTypes.h index 48f821a2..56ec1fa1 100644 --- a/samples/proxy/schema/ProxySharedTypes.h +++ b/samples/proxy/schema/ProxySharedTypes.h @@ -23,7 +23,8 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql::proxy { +namespace graphql { +namespace proxy { enum class [[nodiscard("unnecessary conversion")]] OperationType { @@ -75,6 +76,7 @@ struct [[nodiscard("unnecessary construction")]] QueryInput std::optional variables; }; -} // namespace graphql::proxy +} // namespace proxy +} // namespace graphql #endif // PROXYSHAREDTYPES_H diff --git a/samples/today/nointrospection/TodaySchema.h b/samples/today/nointrospection/TodaySchema.h index 594c9264..80b99eee 100644 --- a/samples/today/nointrospection/TodaySchema.h +++ b/samples/today/nointrospection/TodaySchema.h @@ -25,8 +25,7 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql { -namespace today { +namespace graphql::today { namespace object { class Node; @@ -97,7 +96,6 @@ void AddExpensiveDetails(const std::shared_ptr& typeExpensiv std::shared_ptr GetSchema(); -} // namespace today -} // namespace graphql +} // namespace graphql::today #endif // TODAYSCHEMA_H diff --git a/samples/today/nointrospection/TodaySharedTypes.h b/samples/today/nointrospection/TodaySharedTypes.h index 39774106..b3c7b086 100644 --- a/samples/today/nointrospection/TodaySharedTypes.h +++ b/samples/today/nointrospection/TodaySharedTypes.h @@ -23,7 +23,8 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql::today { +namespace graphql { +namespace today { enum class [[nodiscard("unnecessary conversion")]] TaskState { @@ -232,6 +233,7 @@ struct [[nodiscard("unnecessary construction")]] FirstNestedInput ThirdNestedInput third; }; -} // namespace graphql::today +} // namespace today +} // namespace graphql #endif // TODAYSHAREDTYPES_H diff --git a/samples/today/schema/TodaySchema.h b/samples/today/schema/TodaySchema.h index 594c9264..80b99eee 100644 --- a/samples/today/schema/TodaySchema.h +++ b/samples/today/schema/TodaySchema.h @@ -25,8 +25,7 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql { -namespace today { +namespace graphql::today { namespace object { class Node; @@ -97,7 +96,6 @@ void AddExpensiveDetails(const std::shared_ptr& typeExpensiv std::shared_ptr GetSchema(); -} // namespace today -} // namespace graphql +} // namespace graphql::today #endif // TODAYSCHEMA_H diff --git a/samples/today/schema/TodaySharedTypes.h b/samples/today/schema/TodaySharedTypes.h index 39774106..b3c7b086 100644 --- a/samples/today/schema/TodaySharedTypes.h +++ b/samples/today/schema/TodaySharedTypes.h @@ -23,7 +23,8 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql::today { +namespace graphql { +namespace today { enum class [[nodiscard("unnecessary conversion")]] TaskState { @@ -232,6 +233,7 @@ struct [[nodiscard("unnecessary construction")]] FirstNestedInput ThirdNestedInput third; }; -} // namespace graphql::today +} // namespace today +} // namespace graphql #endif // TODAYSHAREDTYPES_H diff --git a/samples/validation/schema/ValidationSchema.h b/samples/validation/schema/ValidationSchema.h index 0d6a6041..80d071f7 100644 --- a/samples/validation/schema/ValidationSchema.h +++ b/samples/validation/schema/ValidationSchema.h @@ -25,8 +25,7 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql { -namespace validation { +namespace graphql::validation { namespace object { class Sentient; @@ -95,7 +94,6 @@ void AddArgumentsDetails(const std::shared_ptr& typeArgument std::shared_ptr GetSchema(); -} // namespace validation -} // namespace graphql +} // namespace graphql::validation #endif // VALIDATIONSCHEMA_H diff --git a/samples/validation/schema/ValidationSharedTypes.h b/samples/validation/schema/ValidationSharedTypes.h index 71aa4da4..7b963d0a 100644 --- a/samples/validation/schema/ValidationSharedTypes.h +++ b/samples/validation/schema/ValidationSharedTypes.h @@ -23,7 +23,8 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql::validation { +namespace graphql { +namespace validation { enum class [[nodiscard("unnecessary conversion")]] DogCommand { @@ -94,6 +95,7 @@ struct [[nodiscard("unnecessary construction")]] ComplexInput std::optional owner; }; -} // namespace graphql::validation +} // namespace validation +} // namespace graphql #endif // VALIDATIONSHAREDTYPES_H diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index ccf5b518..1a62684a 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -174,7 +174,15 @@ bool Generator::outputSchemaHeader() const noexcept headerFile << R"cpp(#include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" -#include "graphqlservice/internal/Version.h" +)cpp"; + + if (_loader.isIntrospection()) + { + headerFile << R"cpp(#include "graphqlservice/internal/DllExports.h" +)cpp"; + } + + headerFile << R"cpp(#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" )cpp"; @@ -204,8 +212,8 @@ static_assert(graphql::internal::MinorVersion == )cpp" )cpp"; - NamespaceScope graphqlNamespace { headerFile, "graphql" }; - NamespaceScope schemaNamespace { headerFile, _loader.getSchemaNamespace() }; + const auto schemaNamespace = std::format(R"cpp(graphql::{})cpp", _loader.getSchemaNamespace()); + NamespaceScope schemaNamespaceScope { headerFile, schemaNamespace }; NamespaceScope objectNamespace { headerFile, "object", true }; PendingBlankLine pendingSeparator { headerFile }; @@ -449,66 +457,12 @@ static_assert(graphql::internal::MinorVersion == )cpp" headerFile << std::endl; } - NamespaceScope serviceNamespace { headerFile, "service", true }; - if (_loader.isIntrospection()) { headerFile << R"cpp(GRAPHQLSERVICE_EXPORT void AddTypesToSchema(const std::shared_ptr& schema); )cpp"; - - if (!_loader.getEnumTypes().empty() || !_loader.getInputTypes().empty()) - { - if (schemaNamespace.exit()) - { - headerFile << std::endl; - } - - serviceNamespace.enter(); - - headerFile << R"cpp( -#ifdef GRAPHQL_DLLEXPORTS -// Export all of the built-in converters -)cpp"; - - for (const auto& enumType : _loader.getEnumTypes()) - { - headerFile << R"cpp(template <> -GRAPHQLSERVICE_EXPORT )cpp" << _loader.getSchemaNamespace() - << R"cpp(::)cpp" << enumType.cppType << R"cpp( Argument<)cpp" - << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType - << R"cpp(>::convert( - const response::Value& value); -template <> -GRAPHQLSERVICE_EXPORT AwaitableResolver Result<)cpp" - << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType - << R"cpp(>::convert( - AwaitableScalar<)cpp" << _loader.getSchemaNamespace() - << R"cpp(::)cpp" << enumType.cppType - << R"cpp(> result, ResolverParams&& params); -template <> -GRAPHQLSERVICE_EXPORT void Result<)cpp" - << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType - << R"cpp(>::validateScalar( - const response::Value& value); -)cpp"; - } - - for (const auto& inputType : _loader.getInputTypes()) - { - headerFile << R"cpp(template <> -GRAPHQLSERVICE_EXPORT )cpp" << _loader.getSchemaNamespace() - << R"cpp(::)cpp" << inputType.cppType << R"cpp( Argument<)cpp" - << inputType.cppType << R"cpp(>::convert( - const response::Value& value); -)cpp"; - } - - headerFile << R"cpp(#endif // GRAPHQL_DLLEXPORTS - -)cpp"; - } } else { @@ -673,7 +627,15 @@ bool Generator::outputSharedTypesHeader() const noexcept headerFile << R"cpp(#include "graphqlservice/GraphQLResponse.h" -#include "graphqlservice/internal/Version.h" +)cpp"; + + if (_loader.isIntrospection()) + { + headerFile << R"cpp(#include "graphqlservice/internal/DllExports.h" +)cpp"; + } + + headerFile << R"cpp(#include "graphqlservice/internal/Version.h" #include #include @@ -694,8 +656,8 @@ static_assert(graphql::internal::MinorVersion == )cpp" )cpp"; - const auto schemaNamespace = std::format(R"cpp(graphql::{})cpp", _loader.getSchemaNamespace()); - NamespaceScope schemaNamespaceScope { headerFile, schemaNamespace }; + NamespaceScope graphqlNamespace { headerFile, "graphql" }; + NamespaceScope schemaNamespace { headerFile, _loader.getSchemaNamespace() }; PendingBlankLine pendingSeparator { headerFile }; if (!_loader.getEnumTypes().empty()) @@ -901,6 +863,60 @@ static_assert(graphql::internal::MinorVersion == )cpp" } } + if (_loader.isIntrospection()) + { + if (schemaNamespace.exit()) + { + pendingSeparator.add(); + } + + pendingSeparator.reset(); + + NamespaceScope serviceNamespace { headerFile, "service" }; + + headerFile << R"cpp( +#ifdef GRAPHQL_DLLEXPORTS +// Export all of the built-in converters +)cpp"; + + for (const auto& enumType : _loader.getEnumTypes()) + { + headerFile << R"cpp(template <> +GRAPHQLSERVICE_EXPORT )cpp" + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType + << R"cpp( Argument<)cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" + << enumType.cppType << R"cpp(>::convert( + const response::Value& value); +template <> +GRAPHQLSERVICE_EXPORT AwaitableResolver Result<)cpp" + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType + << R"cpp(>::convert( + AwaitableScalar<)cpp" + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType + << R"cpp(> result, ResolverParams&& params); +template <> +GRAPHQLSERVICE_EXPORT void Result<)cpp" + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType + << R"cpp(>::validateScalar( + const response::Value& value); +)cpp"; + } + + for (const auto& inputType : _loader.getInputTypes()) + { + headerFile << R"cpp(template <> +GRAPHQLSERVICE_EXPORT )cpp" + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << inputType.cppType + << R"cpp( Argument<)cpp" << inputType.cppType << R"cpp(>::convert( + const response::Value& value); +)cpp"; + } + + headerFile << R"cpp(#endif // GRAPHQL_DLLEXPORTS + +)cpp"; + } + return true; } @@ -2275,9 +2291,8 @@ Operations::Operations()cpp"; { bool firstValue = true; - sourceFile << R"cpp( static const auto s_names)cpp" - << enumType.cppType << R"cpp( = get)cpp" << enumType.cppType - << R"cpp(Names(); + sourceFile << R"cpp( static const auto s_names)cpp" << enumType.cppType + << R"cpp( = get)cpp" << enumType.cppType << R"cpp(Names(); type)cpp" << enumType.cppType << R"cpp(->AddEnumValues({ )cpp"; diff --git a/src/introspection/IntrospectionSchema.h b/src/introspection/IntrospectionSchema.h index 3ea811b0..b39fe13f 100644 --- a/src/introspection/IntrospectionSchema.h +++ b/src/introspection/IntrospectionSchema.h @@ -11,6 +11,7 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/DllExports.h" #include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" @@ -25,8 +26,7 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql { -namespace introspection { +namespace graphql::introspection { class Schema; class Type; class Field; @@ -54,33 +54,6 @@ void AddDirectiveDetails(const std::shared_ptr& typeDirectiv GRAPHQLSERVICE_EXPORT void AddTypesToSchema(const std::shared_ptr& schema); -} // namespace introspection - -namespace service { - -#ifdef GRAPHQL_DLLEXPORTS -// Export all of the built-in converters -template <> -GRAPHQLSERVICE_EXPORT introspection::TypeKind Argument::convert( - const response::Value& value); -template <> -GRAPHQLSERVICE_EXPORT AwaitableResolver Result::convert( - AwaitableScalar result, ResolverParams&& params); -template <> -GRAPHQLSERVICE_EXPORT void Result::validateScalar( - const response::Value& value); -template <> -GRAPHQLSERVICE_EXPORT introspection::DirectiveLocation Argument::convert( - const response::Value& value); -template <> -GRAPHQLSERVICE_EXPORT AwaitableResolver Result::convert( - AwaitableScalar result, ResolverParams&& params); -template <> -GRAPHQLSERVICE_EXPORT void Result::validateScalar( - const response::Value& value); -#endif // GRAPHQL_DLLEXPORTS - -} // namespace service -} // namespace graphql +} // namespace graphql::introspection #endif // INTROSPECTIONSCHEMA_H diff --git a/src/introspection/IntrospectionSharedTypes.h b/src/introspection/IntrospectionSharedTypes.h index 63b71c2c..9e1d5acb 100644 --- a/src/introspection/IntrospectionSharedTypes.h +++ b/src/introspection/IntrospectionSharedTypes.h @@ -10,6 +10,7 @@ #include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/internal/DllExports.h" #include "graphqlservice/internal/Version.h" #include @@ -23,7 +24,8 @@ static_assert(graphql::internal::MajorVersion == 5, "regenerate with schemagen: major version mismatch"); static_assert(graphql::internal::MinorVersion == 0, "regenerate with schemagen: minor version mismatch"); -namespace graphql::introspection { +namespace graphql { +namespace introspection { enum class TypeKind { @@ -146,6 +148,33 @@ enum class DirectiveLocation }; } -} // namespace graphql::introspection +} // namespace introspection + +namespace service { + +#ifdef GRAPHQL_DLLEXPORTS +// Export all of the built-in converters +template <> +GRAPHQLSERVICE_EXPORT introspection::TypeKind Argument::convert( + const response::Value& value); +template <> +GRAPHQLSERVICE_EXPORT AwaitableResolver Result::convert( + AwaitableScalar result, ResolverParams&& params); +template <> +GRAPHQLSERVICE_EXPORT void Result::validateScalar( + const response::Value& value); +template <> +GRAPHQLSERVICE_EXPORT introspection::DirectiveLocation Argument::convert( + const response::Value& value); +template <> +GRAPHQLSERVICE_EXPORT AwaitableResolver Result::convert( + AwaitableScalar result, ResolverParams&& params); +template <> +GRAPHQLSERVICE_EXPORT void Result::validateScalar( + const response::Value& value); +#endif // GRAPHQL_DLLEXPORTS + +} // namespace service +} // namespace graphql #endif // INTROSPECTIONSHAREDTYPES_H From 1e874c93a501efcd316e8a70b53039268acd4279 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 25 Sep 2024 15:24:51 -0700 Subject: [PATCH 085/123] fix: #324 --- include/graphqlservice/GraphQLService.h | 13 ++++- samples/today/TodayMock.cpp | 12 ++--- src/GraphQLService.cpp | 68 ++++++++++++++----------- 3 files changed, 55 insertions(+), 38 deletions(-) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 381cae3f..99c8aff1 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -249,8 +249,17 @@ class [[nodiscard("unnecessary construction")]] await_async final using Directives = std::vector>; // Traversing a fragment spread adds a new set of directives. -using FragmentDefinitionDirectiveStack = std::list>; -using FragmentSpreadDirectiveStack = std::list; +struct [[nodiscard("unnecessary construction")]] FragmentDefinitionDirectiveStack +{ + const std::reference_wrapper directives; + const std::shared_ptr outer; +}; + +struct [[nodiscard("unnecessary construction")]] FragmentSpreadDirectiveStack +{ + const Directives directives; + const std::shared_ptr outer; +}; // Pass a common bundle of parameters to all of the generated Object::getField accessors in a // SelectionSet diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index 4d808469..236b45cf 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -907,15 +907,15 @@ NestedType::NestedType(service::FieldParams&& params, int depth) : depth(depth) { _capturedParams.push({ { params.operationDirectives }, - params.fragmentDefinitionDirectives->empty() + !params.fragmentDefinitionDirectives ? service::Directives {} - : service::Directives { params.fragmentDefinitionDirectives->front().get() }, - params.fragmentSpreadDirectives->empty() + : service::Directives { params.fragmentDefinitionDirectives->directives.get() }, + !params.fragmentSpreadDirectives ? service::Directives {} - : service::Directives { params.fragmentSpreadDirectives->front() }, - params.inlineFragmentDirectives->empty() + : service::Directives { params.fragmentSpreadDirectives->directives }, + !params.inlineFragmentDirectives ? service::Directives {} - : service::Directives { params.inlineFragmentDirectives->front() }, + : service::Directives { params.inlineFragmentDirectives->directives }, std::move(params.fieldDirectives) }); } diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index 9b704d8b..3d8d53ea 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -244,7 +244,7 @@ void await_worker_queue::resumePending() // Default to immediate synchronous execution. await_async::await_async() : _pimpl { std::static_pointer_cast( - std::make_shared>(std::make_shared())) } + std::make_shared>(std::make_shared())) } { } @@ -252,9 +252,9 @@ await_async::await_async() await_async::await_async(std::launch launch) : _pimpl { ((launch & std::launch::async) == std::launch::async) ? std::static_pointer_cast(std::make_shared>( - std::make_shared())) + std::make_shared())) : std::static_pointer_cast(std::make_shared>( - std::make_shared())) } + std::make_shared())) } { } @@ -896,6 +896,8 @@ class SelectionVisitor const TypeNames& _typeNames; const ResolverMap& _resolvers; + static const Directives s_emptyFragmentDefinitionDirectives; + std::shared_ptr _fragmentDefinitionDirectives; std::shared_ptr _fragmentSpreadDirectives; std::shared_ptr _inlineFragmentDirectives; @@ -903,6 +905,8 @@ class SelectionVisitor std::vector _values; }; +const Directives SelectionVisitor::s_emptyFragmentDefinitionDirectives {}; + SelectionVisitor::SelectionVisitor(const SelectionSetParams& selectionSetParams, const FragmentMap& fragments, const response::Value& variables, const TypeNames& typeNames, const ResolverMap& resolvers, std::size_t count) @@ -917,19 +921,17 @@ SelectionVisitor::SelectionVisitor(const SelectionSetParams& selectionSetParams, , _variables(variables) , _typeNames(typeNames) , _resolvers(resolvers) - , _fragmentDefinitionDirectives { selectionSetParams.fragmentDefinitionDirectives } - , _fragmentSpreadDirectives { selectionSetParams.fragmentSpreadDirectives } - , _inlineFragmentDirectives { selectionSetParams.inlineFragmentDirectives } + , _fragmentDefinitionDirectives { std::make_shared( + FragmentDefinitionDirectiveStack { std::cref(s_emptyFragmentDefinitionDirectives), + selectionSetParams.fragmentDefinitionDirectives }) } + , _fragmentSpreadDirectives { std::make_shared( + FragmentSpreadDirectiveStack { {}, selectionSetParams.fragmentSpreadDirectives }) } + , _inlineFragmentDirectives { std::make_shared( + FragmentSpreadDirectiveStack { {}, selectionSetParams.inlineFragmentDirectives }) } { - static const Directives s_emptyFragmentDefinitionDirectives; - // Traversing a SelectionSet from an Object type field should start tracking new fragment // directives. The outer fragment directives are still there in the FragmentSpreadDirectiveStack // if the field accessors want to inspect them. - _fragmentDefinitionDirectives->push_front(std::cref(s_emptyFragmentDefinitionDirectives)); - _fragmentSpreadDirectives->push_front({}); - _inlineFragmentDirectives->push_front({}); - _names.reserve(count); _values.reserve(count); } @@ -1126,8 +1128,12 @@ void SelectionVisitor::visitFragmentSpread(const peg::ast_node& fragmentSpread) return; } - _fragmentDefinitionDirectives->push_front(itr->second.getDirectives()); - _fragmentSpreadDirectives->push_front(directiveVisitor.getDirectives()); + _fragmentDefinitionDirectives = std::make_shared( + FragmentDefinitionDirectiveStack { itr->second.getDirectives(), + _fragmentDefinitionDirectives }); + _fragmentSpreadDirectives = std::make_shared( + FragmentSpreadDirectiveStack { directiveVisitor.getDirectives(), + _fragmentSpreadDirectives }); const std::size_t count = itr->second.getSelection().children.size(); @@ -1142,8 +1148,8 @@ void SelectionVisitor::visitFragmentSpread(const peg::ast_node& fragmentSpread) visit(*selection); } - _fragmentSpreadDirectives->pop_front(); - _fragmentDefinitionDirectives->pop_front(); + _fragmentSpreadDirectives = _fragmentSpreadDirectives->outer; + _fragmentDefinitionDirectives = _fragmentDefinitionDirectives->outer; } void SelectionVisitor::visitInlineFragment(const peg::ast_node& inlineFragment) @@ -1172,7 +1178,9 @@ void SelectionVisitor::visitInlineFragment(const peg::ast_node& inlineFragment) { peg::on_first_child(inlineFragment, [this, &directiveVisitor](const peg::ast_node& child) { - _inlineFragmentDirectives->push_front(directiveVisitor.getDirectives()); + _inlineFragmentDirectives = std::make_shared( + FragmentSpreadDirectiveStack { directiveVisitor.getDirectives(), + _inlineFragmentDirectives }); const std::size_t count = child.children.size(); @@ -1187,7 +1195,7 @@ void SelectionVisitor::visitInlineFragment(const peg::ast_node& inlineFragment) visit(*selection); } - _inlineFragmentDirectives->pop_front(); + _inlineFragmentDirectives = _inlineFragmentDirectives->outer; }); } } @@ -1438,9 +1446,9 @@ void OperationDefinitionVisitor::visit( _resolverContext, _params->state, _params->directives, - std::make_shared(), - std::make_shared(), - std::make_shared(), + {}, + {}, + {}, std::nullopt, _launch, }; @@ -1855,9 +1863,9 @@ AwaitableSubscribe Request::subscribe(RequestSubscribeParams params) ResolverContext::NotifySubscribe, registration->data->state, registration->data->directives, - std::make_shared(), - std::make_shared(), - std::make_shared(), + {}, + {}, + {}, {}, launch, }; @@ -1917,9 +1925,9 @@ AwaitableUnsubscribe Request::unsubscribe(RequestUnsubscribeParams params) ResolverContext::NotifyUnsubscribe, registration->data->state, registration->data->directives, - std::make_shared(), - std::make_shared(), - std::make_shared(), + {}, + {}, + {}, {}, params.launch, }; @@ -1980,9 +1988,9 @@ AwaitableDeliver Request::deliver(RequestDeliverParams params) const ResolverContext::Subscription, registration->data->state, registration->data->directives, - std::make_shared(), - std::make_shared(), - std::make_shared(), + std::shared_ptr {}, + std::shared_ptr {}, + std::shared_ptr {}, std::nullopt, params.launch, }; From 85c139c6dbfc8e43f9992b23767d4723151abf42 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 25 Sep 2024 15:47:28 -0700 Subject: [PATCH 086/123] fix: explicitly type default initializers for clarity --- src/GraphQLService.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index 3d8d53ea..63bc919a 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -1446,9 +1446,9 @@ void OperationDefinitionVisitor::visit( _resolverContext, _params->state, _params->directives, - {}, - {}, - {}, + std::shared_ptr {}, + std::shared_ptr {}, + std::shared_ptr {}, std::nullopt, _launch, }; @@ -1863,10 +1863,10 @@ AwaitableSubscribe Request::subscribe(RequestSubscribeParams params) ResolverContext::NotifySubscribe, registration->data->state, registration->data->directives, - {}, - {}, - {}, - {}, + std::shared_ptr {}, + std::shared_ptr {}, + std::shared_ptr {}, + std::nullopt, launch, }; @@ -1925,10 +1925,10 @@ AwaitableUnsubscribe Request::unsubscribe(RequestUnsubscribeParams params) ResolverContext::NotifyUnsubscribe, registration->data->state, registration->data->directives, - {}, - {}, - {}, - {}, + std::shared_ptr {}, + std::shared_ptr {}, + std::shared_ptr {}, + std::nullopt, params.launch, }; From 9505d83fa2d311a0f5198b1526ce4a653857a5d7 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 12 Oct 2024 20:33:24 -0700 Subject: [PATCH 087/123] feat: deferred ResolverVisitor --- include/graphqlservice/GraphQLService.h | 282 ++++++++++- include/graphqlservice/Service.ixx | 3 + samples/learn/schema/StarWarsSharedTypes.cpp | 6 +- samples/proxy/schema/ProxySharedTypes.cpp | 6 +- .../nointrospection/TodaySharedTypes.cpp | 6 +- samples/today/schema/TodaySharedTypes.cpp | 6 +- .../schema/ValidationSharedTypes.cpp | 12 +- src/GraphQLService.cpp | 461 ++++++++++++++++-- src/SchemaGenerator.cpp | 11 +- .../IntrospectionSharedTypes.cpp | 12 +- 10 files changed, 702 insertions(+), 103 deletions(-) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 99c8aff1..5d9ece1a 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -487,6 +487,156 @@ class [[nodiscard("unnecessary construction")]] AwaitableObject std::variant> _value; }; +// Type-erased visitor for resolvers. +class [[nodiscard("unnecessary construction")]] ResolverVisitor final + : public std::enable_shared_from_this +{ +private: + struct Concept + { + virtual ~Concept() = default; + + virtual void add_value(std::shared_ptr&& value) = 0; + + virtual void reserve(std::size_t count) = 0; + + virtual void start_object() = 0; + virtual void add_member(std::string&& key) = 0; + virtual void end_object() = 0; + + virtual void start_array() = 0; + virtual void end_array() = 0; + + virtual void add_null() = 0; + virtual void add_string(std::string&& value) = 0; + virtual void add_enum(std::string&& value) = 0; + virtual void add_id(response::IdType&& value) = 0; + virtual void add_bool(bool value) = 0; + virtual void add_int(int value) = 0; + virtual void add_float(double value) = 0; + + virtual void add_error(schema_error&& error) = 0; + }; + + template + struct Model : Concept + { + explicit Model(std::shared_ptr pimpl) noexcept + : _pimpl { std::move(pimpl) } + { + } + + void add_value(std::shared_ptr&& value) final + { + _pimpl->add_value(std::move(value)); + } + + void reserve(std::size_t count) final + { + _pimpl->reserve(count); + } + + void start_object() final + { + _pimpl->start_object(); + } + + void add_member(std::string&& key) final + { + _pimpl->add_member(std::move(key)); + } + + void end_object() final + { + _pimpl->end_object(); + } + + void start_array() final + { + _pimpl->start_array(); + } + + void end_array() final + { + _pimpl->end_array(); + } + + void add_null() final + { + _pimpl->add_null(); + } + + void add_string(std::string&& value) final + { + _pimpl->add_string(std::move(value)); + } + + void add_enum(std::string&& value) final + { + _pimpl->add_enum(std::move(value)); + } + + void add_id(response::IdType&& value) final + { + _pimpl->add_id(std::move(value)); + } + + void add_bool(bool value) final + { + _pimpl->add_bool(value); + } + + void add_int(int value) final + { + _pimpl->add_int(value); + } + + void add_float(double value) final + { + _pimpl->add_float(value); + } + + void add_error(schema_error&& error) final + { + _pimpl->add_error(std::move(error)); + } + + private: + std::shared_ptr _pimpl; + }; + + const std::shared_ptr _concept; + +public: + template + ResolverVisitor(std::shared_ptr writer) noexcept + : _concept { std::static_pointer_cast( + std::make_shared>(std::move(writer))) } + { + } + + GRAPHQLSERVICE_EXPORT void add_value(std::shared_ptr&& value); + + GRAPHQLSERVICE_EXPORT void reserve(std::size_t count); + + GRAPHQLSERVICE_EXPORT void start_object(); + GRAPHQLSERVICE_EXPORT void add_member(std::string&& key); + GRAPHQLSERVICE_EXPORT void end_object(); + + GRAPHQLSERVICE_EXPORT void start_array(); + GRAPHQLSERVICE_EXPORT void end_array(); + + GRAPHQLSERVICE_EXPORT void add_null(); + GRAPHQLSERVICE_EXPORT void add_string(std::string&& value); + GRAPHQLSERVICE_EXPORT void add_enum(std::string&& value); + GRAPHQLSERVICE_EXPORT void add_id(response::IdType&& value); + GRAPHQLSERVICE_EXPORT void add_bool(bool value); + GRAPHQLSERVICE_EXPORT void add_int(int value); + GRAPHQLSERVICE_EXPORT void add_float(double value); + + GRAPHQLSERVICE_EXPORT void add_error(schema_error&& error); +}; + // Fragments are referenced by name and have a single type condition (except for inline // fragments, where the type condition is common but optional). They contain a set of fields // (with optional aliases and sub-selections) and potentially references to other fragments. @@ -535,11 +685,104 @@ struct [[nodiscard("unnecessary construction")]] ResolverParams : SelectionSetPa const response::Value& variables; }; +// Pending token for ResolverVisitor. +struct [[nodiscard("unnecessary construction")]] ResultToken +{ + using OpaqueValue = std::shared_ptr; + + struct Reserve + { + std::size_t capacity; + }; + + struct StartObject + { + }; + + struct AddMember + { + std::string key; + }; + + struct EndObject + { + }; + + struct StartArray + { + }; + + struct EndArray + { + }; + + struct NullValue + { + }; + + struct StringValue + { + std::string value; + }; + + struct EnumValue + { + std::string value; + }; + + struct IdValue + { + response::IdType value; + }; + + struct BoolValue + { + bool value; + }; + + struct IntValue + { + int value; + }; + + struct FloatValue + { + double value; + }; + + GRAPHQLSERVICE_EXPORT explicit ResultToken(OpaqueValue&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(Reserve&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(StartObject&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(AddMember&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(EndObject&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(StartArray&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(EndArray&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(NullValue&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(StringValue&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(EnumValue&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(IdValue&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(BoolValue&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(IntValue&& value); + GRAPHQLSERVICE_EXPORT explicit ResultToken(FloatValue&& value); + + GRAPHQLSERVICE_EXPORT void visit(const std::shared_ptr& visitor) &&; + +private: + using variant_type = + std::variant; + + variant_type _value; +}; + // Propagate data and errors together without bundling them into a response::Value struct until // we're ready to return from the top level Operation. struct [[nodiscard("unnecessary construction")]] ResolverResult { - response::Value data; + GRAPHQLSERVICE_EXPORT response::Value toValue() &&; + GRAPHQLSERVICE_EXPORT void visit(const std::shared_ptr& visitor) &&; + + std::list data {}; std::list errors {}; }; @@ -1019,7 +1262,7 @@ struct ModifiedResult if (!awaitedResult) { - co_return ResolverResult {}; + co_return ResolverResult { { ResultToken { ResultToken::NullValue {} } } }; } auto modifiedResult = @@ -1046,8 +1289,8 @@ struct ModifiedResult if (value) { ModifiedResult::validateScalar(*value); - co_return ResolverResult { response::Value { - std::shared_ptr { std::move(value) } } }; + co_return ResolverResult { { ResultToken { + ResultToken::OpaqueValue { std::shared_ptr { std::move(value) } } } } }; } } @@ -1060,7 +1303,7 @@ struct ModifiedResult if (!awaitedResult) { - co_return ResolverResult {}; + co_return ResolverResult { { ResultToken { ResultToken::NullValue {} } } }; } auto modifiedResult = co_await ModifiedResult::convert(std::move(*awaitedResult), @@ -1083,8 +1326,8 @@ struct ModifiedResult if (value) { ModifiedResult::validateScalar(*value); - co_return ResolverResult { response::Value { - std::shared_ptr { std::move(value) } } }; + co_return ResolverResult { { ResultToken { + ResultToken::OpaqueValue { std::shared_ptr { std::move(value) } } } } }; } } @@ -1128,9 +1371,10 @@ struct ModifiedResult } } - ResolverResult document { response::Value { response::Type::List } }; + ResolverResult document; - document.data.reserve(children.size()); + document.data.push_back(ResultToken { ResultToken::StartArray {} }); + document.data.push_back(ResultToken { ResultToken::Reserve { children.size() } }); std::get(params.errorPath->segment) = 0; for (auto& child : children) @@ -1141,11 +1385,11 @@ struct ModifiedResult auto value = co_await std::move(child); - document.data.emplace_back(std::move(value.data)); + document.data.splice(document.data.end(), std::move(value.data)); if (!value.errors.empty()) { - document.errors.splice(document.errors.end(), value.errors); + document.errors.splice(document.errors.end(), std::move(value.errors)); } } catch (schema_exception& scx) @@ -1171,6 +1415,8 @@ struct ModifiedResult ++std::get(params.errorPath->segment); } + document.data.push_back(ResultToken { ResultToken::EndArray {} }); + co_return document; } @@ -1213,7 +1459,7 @@ struct ModifiedResult } using ResolverCallback = - std::function::type, const ResolverParams&)>; + std::function::type, const ResolverParams&)>; [[nodiscard("unnecessary call")]] static AwaitableResolver resolve( typename ResultTraits::future_type result, ResolverParams&& paramsArg, @@ -1226,7 +1472,8 @@ struct ModifiedResult if (value) { Result::validateScalar(*value); - co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } }; + co_return ResolverResult { { ResultToken { + ResultToken::OpaqueValue { std::shared_ptr { std::move(value) } } } } }; } auto pendingResolver = std::move(resolver); @@ -1238,7 +1485,14 @@ struct ModifiedResult try { co_await params.launch; - document.data = pendingResolver(co_await result, params); + auto value = pendingResolver(co_await result, params); + + document.data.splice(document.data.end(), std::move(value.data)); + + if (!value.errors.empty()) + { + document.errors.splice(document.errors.end(), std::move(value.errors)); + } } catch (schema_exception& scx) { diff --git a/include/graphqlservice/Service.ixx b/include/graphqlservice/Service.ixx index a7cd01f2..f28b500d 100644 --- a/include/graphqlservice/Service.ixx +++ b/include/graphqlservice/Service.ixx @@ -66,10 +66,13 @@ using service::FieldParams; using service::AwaitableScalar; using service::AwaitableObject; +using service::ResolverVisitor; + using service::Fragment; using service::FragmentMap; using service::ResolverParams; +using service::ResultToken; using service::ResolverResult; using service::AwaitableResolver; using service::Resolver; diff --git a/samples/learn/schema/StarWarsSharedTypes.cpp b/samples/learn/schema/StarWarsSharedTypes.cpp index 3bfcae45..03051730 100644 --- a/samples/learn/schema/StarWarsSharedTypes.cpp +++ b/samples/learn/schema/StarWarsSharedTypes.cpp @@ -50,11 +50,7 @@ service::AwaitableResolver Result::convert(service::AwaitableSca return ModifiedResult::resolve(std::move(result), std::move(params), [](learn::Episode value, const ResolverParams&) { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesEpisode[static_cast(value)] }); - - return resolvedResult; + return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesEpisode[static_cast(value)] } } } } }; }); } diff --git a/samples/proxy/schema/ProxySharedTypes.cpp b/samples/proxy/schema/ProxySharedTypes.cpp index 66aafa00..b04e6076 100644 --- a/samples/proxy/schema/ProxySharedTypes.cpp +++ b/samples/proxy/schema/ProxySharedTypes.cpp @@ -50,11 +50,7 @@ service::AwaitableResolver Result::convert(service::Awaita return ModifiedResult::resolve(std::move(result), std::move(params), [](proxy::OperationType value, const ResolverParams&) { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesOperationType[static_cast(value)] }); - - return resolvedResult; + return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesOperationType[static_cast(value)] } } } } }; }); } diff --git a/samples/today/nointrospection/TodaySharedTypes.cpp b/samples/today/nointrospection/TodaySharedTypes.cpp index d3a0c4a0..da5e03da 100644 --- a/samples/today/nointrospection/TodaySharedTypes.cpp +++ b/samples/today/nointrospection/TodaySharedTypes.cpp @@ -50,11 +50,7 @@ service::AwaitableResolver Result::convert(service::AwaitableS return ModifiedResult::resolve(std::move(result), std::move(params), [](today::TaskState value, const ResolverParams&) { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); - - return resolvedResult; + return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesTaskState[static_cast(value)] } } } } }; }); } diff --git a/samples/today/schema/TodaySharedTypes.cpp b/samples/today/schema/TodaySharedTypes.cpp index d3a0c4a0..da5e03da 100644 --- a/samples/today/schema/TodaySharedTypes.cpp +++ b/samples/today/schema/TodaySharedTypes.cpp @@ -50,11 +50,7 @@ service::AwaitableResolver Result::convert(service::AwaitableS return ModifiedResult::resolve(std::move(result), std::move(params), [](today::TaskState value, const ResolverParams&) { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); - - return resolvedResult; + return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesTaskState[static_cast(value)] } } } } }; }); } diff --git a/samples/validation/schema/ValidationSharedTypes.cpp b/samples/validation/schema/ValidationSharedTypes.cpp index 47c18527..84837b35 100644 --- a/samples/validation/schema/ValidationSharedTypes.cpp +++ b/samples/validation/schema/ValidationSharedTypes.cpp @@ -50,11 +50,7 @@ service::AwaitableResolver Result::convert(service::Awai return ModifiedResult::resolve(std::move(result), std::move(params), [](validation::DogCommand value, const ResolverParams&) { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesDogCommand[static_cast(value)] }); - - return resolvedResult; + return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesDogCommand[static_cast(value)] } } } } }; }); } @@ -106,11 +102,7 @@ service::AwaitableResolver Result::convert(service::Awai return ModifiedResult::resolve(std::move(result), std::move(params), [](validation::CatCommand value, const ResolverParams&) { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesCatCommand[static_cast(value)] }); - - return resolvedResult; + return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesCatCommand[static_cast(value)] } } } } }; }); } diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index 63bc919a..57987cea 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -11,6 +11,7 @@ #include #include #include +#include using namespace std::literals; @@ -273,6 +274,81 @@ void await_async::await_resume() const _pimpl->await_resume(); } +void ResolverVisitor::add_value(std::shared_ptr&& value) +{ + _concept->add_value(std::move(value)); +} + +void ResolverVisitor::reserve(std::size_t count) +{ + _concept->reserve(count); +} + +void ResolverVisitor::start_object() +{ + _concept->start_object(); +} + +void ResolverVisitor::add_member(std::string&& key) +{ + _concept->add_member(std::move(key)); +} + +void ResolverVisitor::end_object() +{ + _concept->end_object(); +} + +void ResolverVisitor::start_array() +{ + _concept->start_array(); +} + +void ResolverVisitor::end_array() +{ + _concept->end_array(); +} + +void ResolverVisitor::add_null() +{ + _concept->add_null(); +} + +void ResolverVisitor::add_string(std::string&& value) +{ + _concept->add_string(std::move(value)); +} + +void ResolverVisitor::add_enum(std::string&& value) +{ + _concept->add_enum(std::move(value)); +} + +void ResolverVisitor::add_id(response::IdType&& value) +{ + _concept->add_id(std::move(value)); +} + +void ResolverVisitor::add_bool(bool value) +{ + _concept->add_bool(value); +} + +void ResolverVisitor::add_int(int value) +{ + _concept->add_int(value); +} + +void ResolverVisitor::add_float(double value) +{ + _concept->add_float(value); +} + +void ResolverVisitor::add_error(schema_error&& error) +{ + _concept->add_error(std::move(error)); +} + FieldParams::FieldParams(SelectionSetParams&& selectionSetParams, Directives directives) : SelectionSetParams(std::move(selectionSetParams)) , fieldDirectives(std::move(directives)) @@ -620,6 +696,323 @@ schema_location ResolverParams::getLocation() const return { position.line, position.column }; } +ResultToken::ResultToken(OpaqueValue&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(Reserve&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(StartObject&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(AddMember&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(EndObject&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(StartArray&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(EndArray&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(NullValue&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(StringValue&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(EnumValue&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(IdValue&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(BoolValue&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(IntValue&& value) + : _value { std::move(value) } +{ +} + +ResultToken::ResultToken(FloatValue&& value) + : _value { std::move(value) } +{ +} + +void ResultToken::visit(const std::shared_ptr& visitor) && +{ + std::visit( + [&visitor](auto&& value) { + using value_type = std::decay_t; + + if constexpr (std::is_same_v) + { + visitor->add_value(std::move(value)); + } + else if constexpr (std::is_same_v) + { + visitor->reserve(value.capacity); + } + else if constexpr (std::is_same_v) + { + visitor->start_object(); + } + else if constexpr (std::is_same_v) + { + visitor->add_member(std::move(value.key)); + } + else if constexpr (std::is_same_v) + { + visitor->end_object(); + } + else if constexpr (std::is_same_v) + { + visitor->start_array(); + } + else if constexpr (std::is_same_v) + { + visitor->end_array(); + } + else if constexpr (std::is_same_v) + { + visitor->add_null(); + } + else if constexpr (std::is_same_v) + { + visitor->add_string(std::move(value.value)); + } + else if constexpr (std::is_same_v) + { + visitor->add_enum(std::move(value.value)); + } + else if constexpr (std::is_same_v) + { + visitor->add_id(std::move(value.value)); + } + else if constexpr (std::is_same_v) + { + visitor->add_bool(value.value); + } + else if constexpr (std::is_same_v) + { + visitor->add_int(value.value); + } + else if constexpr (std::is_same_v) + { + visitor->add_float(value.value); + } + }, + std::move(_value)); +} + +class ResolverResultVisitor +{ +public: + explicit ResolverResultVisitor() noexcept; + + void add_value(std::shared_ptr&& value); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void add_error(schema_error&& error); + + response::Value document(); + +private: + void add_value(response::Value&& value); + + response::Value _data {}; + std::list _errors {}; + std::stack _values {}; + std::stack _keys {}; +}; + +ResolverResultVisitor::ResolverResultVisitor() noexcept +{ +} + +void ResolverResultVisitor::add_value(std::shared_ptr&& value) +{ + add_value(response::Value { std::move(value) }); +} + +void ResolverResultVisitor::reserve(std::size_t count) +{ + _values.top().reserve(count); +} + +void ResolverResultVisitor::start_object() +{ + _values.push(response::Value { response::Type::Map }); +} + +void ResolverResultVisitor::add_member(std::string&& key) +{ + _keys.push(std::move(key)); +} + +void ResolverResultVisitor::end_object() +{ + auto value = std::move(_values.top()); + + _values.pop(); + add_value(std::move(value)); +} + +void ResolverResultVisitor::start_array() +{ + _values.push(response::Value { response::Type::List }); +} + +void ResolverResultVisitor::end_array() +{ + auto value = std::move(_values.top()); + + _values.pop(); + add_value(std::move(value)); +} + +void ResolverResultVisitor::add_null() +{ + add_value(response::Value {}); +} + +void ResolverResultVisitor::add_string(std::string&& value) +{ + add_value(response::Value { std::move(value) }); +} + +void ResolverResultVisitor::add_enum(std::string&& value) +{ + response::Value enumValue { response::Type::EnumValue }; + + enumValue.set(std::move(value)); + add_value(std::move(enumValue)); +} + +void ResolverResultVisitor::add_id(response::IdType&& value) +{ + add_value(response::Value { std::move(value) }); +} + +void ResolverResultVisitor::add_bool(bool value) +{ + add_value(response::Value { std::move(value) }); +} + +void ResolverResultVisitor::add_int(int value) +{ + add_value(response::Value { std::move(value) }); +} + +void ResolverResultVisitor::add_float(double value) +{ + add_value(response::Value { std::move(value) }); +} + +void ResolverResultVisitor::add_error(schema_error&& error) +{ + _errors.push_back(std::move(error)); +} + +response::Value ResolverResultVisitor::document() +{ + response::Value document { response::Type::Map }; + + document.emplace_back(std::string { strData }, std::move(_data)); + + if (!_errors.empty()) + { + document.emplace_back(std::string { strErrors }, buildErrorValues(std::move(_errors))); + } + + return document; +} + +void ResolverResultVisitor::add_value(response::Value&& value) +{ + if (_values.empty()) + { + _data = std::move(value); + return; + } + + switch (_values.top().type()) + { + case response::Type::Map: + _values.top().emplace_back(std::move(_keys.top()), std::move(value)); + _keys.pop(); + break; + + case response::Type::List: + _values.top().emplace_back(std::move(value)); + break; + + default: + throw std::logic_error("Invalid call to Value::emplace_back"); + break; + } +} + +response::Value ResolverResult::toValue() && +{ + auto visitor = std::make_shared(); + + (std::move(*this)).visit(std::make_shared(visitor)); + + return visitor->document(); +} + +void ResolverResult::visit(const std::shared_ptr& visitor) && +{ + for (auto& token : data) + { + std::move(token).visit(visitor); + } + + for (auto& error : errors) + { + visitor->add_error(std::move(error)); + } +} + template <> int Argument::convert(const response::Value& value) { @@ -703,7 +1096,7 @@ AwaitableResolver Result::convert(AwaitableScalar result, ResolverPara return ModifiedResult::resolve(std::move(result), std::move(params), [](int&& value, const ResolverParams&) { - return response::Value(value); + return ResolverResult { { ResultToken { ResultToken::IntValue { value } } } }; }); } @@ -715,7 +1108,7 @@ AwaitableResolver Result::convert(AwaitableScalar result, Resolv return ModifiedResult::resolve(std::move(result), std::move(params), [](double&& value, const ResolverParams&) { - return response::Value(value); + return ResolverResult { { ResultToken { ResultToken::FloatValue { value } } } }; }); } @@ -728,7 +1121,8 @@ AwaitableResolver Result::convert( return ModifiedResult::resolve(std::move(result), std::move(params), [](std::string&& value, const ResolverParams&) { - return response::Value(std::move(value)); + return ResolverResult { { ResultToken { + ResultToken::StringValue { std::move(value) } } } }; }); } @@ -740,7 +1134,7 @@ AwaitableResolver Result::convert(AwaitableScalar result, ResolverPa return ModifiedResult::resolve(std::move(result), std::move(params), [](bool&& value, const ResolverParams&) { - return response::Value(value); + return ResolverResult { { ResultToken { ResultToken::BoolValue { value } } } }; }); } @@ -753,7 +1147,8 @@ AwaitableResolver Result::convert( return ModifiedResult::resolve(std::move(result), std::move(params), [](response::Value&& value, const ResolverParams&) { - return response::Value(std::move(value)); + return ResolverResult { { ResultToken { ResultToken::OpaqueValue { + std::make_shared(std::move(value)) } } } }; }); } @@ -766,7 +1161,7 @@ AwaitableResolver Result::convert( return ModifiedResult::resolve(std::move(result), std::move(params), [](response::IdType&& value, const ResolverParams&) { - return response::Value(std::move(value)); + return ResolverResult { { ResultToken { ResultToken::IdValue { std::move(value) } } } }; }); } @@ -799,7 +1194,7 @@ AwaitableResolver Result::convert( if (!awaitedResult) { - co_return ResolverResult {}; + co_return ResolverResult { { ResultToken { ResultToken::NullValue {} } } }; } auto document = co_await awaitedResult->resolve(params, @@ -1228,9 +1623,10 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, auto children = visitor.getValues(); const auto launch = selectionSetParams.launch; - ResolverResult document { response::Value { response::Type::Map } }; + ResolverResult document {}; - document.data.reserve(children.size()); + document.data.push_back(ResultToken { ResultToken::StartObject {} }); + document.data.push_back(ResultToken { ResultToken::Reserve { children.size() } }); const auto parent = selectionSetParams.errorPath ? std::make_optional(std::cref(*selectionSetParams.errorPath)) @@ -1244,19 +1640,13 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, auto value = co_await std::move(child.result); - if (!document.data.emplace_back(std::string { child.name }, std::move(value.data))) - { - auto message = std::format("Ambiguous field error name: {}", child.name); - field_path path { parent, path_segment { child.name } }; - - document.errors.push_back({ std::move(message), - child.location.value_or(schema_location {}), - buildErrorPath(std::make_optional(path)) }); - } + document.data.push_back( + ResultToken { ResultToken::AddMember { std::string { child.name } } }); + document.data.splice(document.data.end(), std::move(value.data)); if (!value.errors.empty()) { - document.errors.splice(document.errors.end(), value.errors); + document.errors.splice(document.errors.end(), std::move(value.errors)); } } catch (schema_exception& scx) @@ -1268,7 +1658,9 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, std::ranges::copy(errors, std::back_inserter(document.errors)); } - document.data.emplace_back(std::string { child.name }, {}); + document.data.push_back( + ResultToken { ResultToken::AddMember { std::string { child.name } } }); + document.data.push_back(ResultToken { ResultToken::NullValue {} }); } catch (const std::exception& ex) { @@ -1279,10 +1671,14 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, document.errors.push_back({ std::move(message), child.location.value_or(schema_location {}), buildErrorPath(std::make_optional(path)) }); - document.data.emplace_back(std::string { child.name }, {}); + document.data.push_back( + ResultToken { ResultToken::AddMember { std::string { child.name } } }); + document.data.push_back(ResultToken { ResultToken::NullValue {} }); } } + document.data.push_back(ResultToken { ResultToken::EndObject {} }); + co_return std::move(document); } @@ -1380,7 +1776,7 @@ AwaitableResolver OperationDefinitionVisitor::getValue() { if (!_result) { - co_return ResolverResult {}; + co_return ResolverResult { { ResultToken { ResultToken::NullValue {} } } }; } auto result = std::move(*_result); @@ -1814,18 +2210,7 @@ response::AwaitableValue Request::resolve(RequestResolveParams params) const co_await params.launch; operationVisitor.visit(operationType, *operationDefinition); - auto result = co_await operationVisitor.getValue(); - response::Value document { response::Type::Map }; - - document.emplace_back(std::string { strData }, std::move(result.data)); - - if (!result.errors.empty()) - { - document.emplace_back(std::string { strErrors }, - buildErrorValues(std::move(result.errors))); - } - - co_return std::move(document); + co_return (co_await operationVisitor.getValue()).toValue(); } catch (schema_exception& ex) { @@ -2006,13 +2391,7 @@ AwaitableDeliver Request::deliver(RequestDeliverParams params) const registration->data->fragments, registration->data->variables); - document.emplace_back(std::string { strData }, std::move(result.data)); - - if (!result.errors.empty()) - { - document.emplace_back(std::string { strErrors }, - buildErrorValues(std::move(result.errors))); - } + document = std::move(result).toValue(); } catch (schema_exception& ex) { diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 1a62684a..94980317 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -1685,12 +1685,8 @@ service::AwaitableResolver Result<)cpp" []()cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType << R"cpp( value, const ResolverParams&) { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_names)cpp" - << enumType.cppType << R"cpp([static_cast(value)] }); - - return resolvedResult; + return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_names)cpp" + << enumType.cppType << R"cpp([static_cast(value)] } } } } }; }); } @@ -2492,8 +2488,7 @@ Operations::Operations()cpp"; )cpp"; } sourceFile << R"cpp(}, )cpp" - << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") - << R"cpp()); + << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") << R"cpp()); )cpp"; } } diff --git a/src/introspection/IntrospectionSharedTypes.cpp b/src/introspection/IntrospectionSharedTypes.cpp index 5b1892fe..a4f3f8de 100644 --- a/src/introspection/IntrospectionSharedTypes.cpp +++ b/src/introspection/IntrospectionSharedTypes.cpp @@ -50,11 +50,7 @@ service::AwaitableResolver Result::convert(service::Awa return ModifiedResult::resolve(std::move(result), std::move(params), [](introspection::TypeKind value, const ResolverParams&) { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesTypeKind[static_cast(value)] }); - - return resolvedResult; + return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesTypeKind[static_cast(value)] } } } } }; }); } @@ -106,11 +102,7 @@ service::AwaitableResolver Result::convert(ser return ModifiedResult::resolve(std::move(result), std::move(params), [](introspection::DirectiveLocation value, const ResolverParams&) { - response::Value resolvedResult(response::Type::EnumValue); - - resolvedResult.set(std::string { s_namesDirectiveLocation[static_cast(value)] }); - - return resolvedResult; + return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesDirectiveLocation[static_cast(value)] } } } } }; }); } From 8bf5f5d016a9fbceaee69fb6b6fc115a6ad3ab62 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 12 Oct 2024 20:46:14 -0700 Subject: [PATCH 088/123] fix: variable shadowing --- include/graphqlservice/GraphQLService.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 5d9ece1a..135dde60 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -1485,14 +1485,7 @@ struct ModifiedResult try { co_await params.launch; - auto value = pendingResolver(co_await result, params); - - document.data.splice(document.data.end(), std::move(value.data)); - - if (!value.errors.empty()) - { - document.errors.splice(document.errors.end(), std::move(value.errors)); - } + document = pendingResolver(co_await result, params); } catch (schema_exception& scx) { From 17a98841fa4af07f6bc231286d71a342703d2f17 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 12 Oct 2024 22:15:36 -0700 Subject: [PATCH 089/123] feat: add visitor APIs --- include/graphqlservice/GraphQLService.h | 21 ++++++-- include/graphqlservice/Service.ixx | 3 ++ src/GraphQLService.cpp | 72 +++++++++++++++++-------- 3 files changed, 69 insertions(+), 27 deletions(-) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 135dde60..fd3bbebe 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -516,6 +516,8 @@ class [[nodiscard("unnecessary construction")]] ResolverVisitor final virtual void add_float(double value) = 0; virtual void add_error(schema_error&& error) = 0; + + virtual void complete() = 0; }; template @@ -601,6 +603,11 @@ class [[nodiscard("unnecessary construction")]] ResolverVisitor final _pimpl->add_error(std::move(error)); } + void complete() final + { + _pimpl->complete(); + } + private: std::shared_ptr _pimpl; }; @@ -635,6 +642,8 @@ class [[nodiscard("unnecessary construction")]] ResolverVisitor final GRAPHQLSERVICE_EXPORT void add_float(double value); GRAPHQLSERVICE_EXPORT void add_error(schema_error&& error); + + GRAPHQLSERVICE_EXPORT void complete(); }; // Fragments are referenced by name and have a single type condition (except for inline @@ -779,7 +788,6 @@ struct [[nodiscard("unnecessary construction")]] ResultToken // we're ready to return from the top level Operation. struct [[nodiscard("unnecessary construction")]] ResolverResult { - GRAPHQLSERVICE_EXPORT response::Value toValue() &&; GRAPHQLSERVICE_EXPORT void visit(const std::shared_ptr& visitor) &&; std::list data {}; @@ -1526,11 +1534,14 @@ using ObjectResult = ModifiedResult; // Subscription callbacks receive the response::Value representing the result of evaluating the // SelectionSet against the payload. using SubscriptionCallback = std::function; +using SubscriptionVisitor = std::function()>; +using SubscriptionCallbackOrVisitor = std::variant; // Subscriptions are stored in maps using these keys. using SubscriptionKey = std::size_t; using SubscriptionName = std::string; +using AwaitableVisit = internal::Awaitable; using AwaitableSubscribe = internal::Awaitable; using AwaitableUnsubscribe = internal::Awaitable; using AwaitableDeliver = internal::Awaitable; @@ -1552,7 +1563,7 @@ struct [[nodiscard("unnecessary construction")]] RequestResolveParams struct [[nodiscard("unnecessary construction")]] RequestSubscribeParams { // Callback which receives the event data. - SubscriptionCallback callback; + SubscriptionCallbackOrVisitor callback; // Required query information. peg::ast query; @@ -1643,7 +1654,7 @@ struct [[nodiscard("unnecessary construction")]] SubscriptionData { explicit SubscriptionData(std::shared_ptr data, SubscriptionName&& field, response::Value arguments, Directives fieldDirectives, peg::ast&& query, - std::string&& operationName, SubscriptionCallback&& callback, + std::string&& operationName, SubscriptionCallbackOrVisitor&& callback, const peg::ast_node& selection); std::shared_ptr data; @@ -1653,7 +1664,7 @@ struct [[nodiscard("unnecessary construction")]] SubscriptionData Directives fieldDirectives; peg::ast query; std::string operationName; - SubscriptionCallback callback; + SubscriptionCallbackOrVisitor callback; const peg::ast_node& selection; }; @@ -1688,6 +1699,8 @@ class [[nodiscard("unnecessary construction")]] Request [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT response::AwaitableValue resolve( RequestResolveParams params) const; + [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT AwaitableVisit visit( + RequestResolveParams params, const std::shared_ptr& resolverVisitor) const; [[nodiscard("leaked subscription")]] GRAPHQLSERVICE_EXPORT AwaitableSubscribe subscribe( RequestSubscribeParams params); [[nodiscard("potentially leaked subscription")]] GRAPHQLSERVICE_EXPORT AwaitableUnsubscribe diff --git a/include/graphqlservice/Service.ixx b/include/graphqlservice/Service.ixx index f28b500d..3e62fdeb 100644 --- a/include/graphqlservice/Service.ixx +++ b/include/graphqlservice/Service.ixx @@ -103,9 +103,12 @@ using modified_result::ScalarResult; using modified_result::ObjectResult; using service::SubscriptionCallback; +using service::SubscriptionVisitor; +using service::SubscriptionCallbackOrVisitor; using service::SubscriptionKey; using service::SubscriptionName; +using service::AwaitableVisit; using service::AwaitableSubscribe; using service::AwaitableUnsubscribe; using service::AwaitableDeliver; diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index 57987cea..f711502b 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -349,6 +349,11 @@ void ResolverVisitor::add_error(schema_error&& error) _concept->add_error(std::move(error)); } +void ResolverVisitor::complete() +{ + _concept->complete(); +} + FieldParams::FieldParams(SelectionSetParams&& selectionSetParams, Directives directives) : SelectionSetParams(std::move(selectionSetParams)) , fieldDirectives(std::move(directives)) @@ -852,6 +857,7 @@ class ResolverResultVisitor void add_int(int value); void add_float(double value); void add_error(schema_error&& error); + void complete(); response::Value document(); @@ -952,6 +958,10 @@ void ResolverResultVisitor::add_error(schema_error&& error) _errors.push_back(std::move(error)); } +void ResolverResultVisitor::complete() +{ +} + response::Value ResolverResultVisitor::document() { response::Value document { response::Type::Map }; @@ -991,15 +1001,6 @@ void ResolverResultVisitor::add_value(response::Value&& value) } } -response::Value ResolverResult::toValue() && -{ - auto visitor = std::make_shared(); - - (std::move(*this)).visit(std::make_shared(visitor)); - - return visitor->document(); -} - void ResolverResult::visit(const std::shared_ptr& visitor) && { for (auto& token : data) @@ -1011,6 +1012,8 @@ void ResolverResult::visit(const std::shared_ptr& visitor) && { visitor->add_error(std::move(error)); } + + visitor->complete(); } template <> @@ -1857,7 +1860,8 @@ void OperationDefinitionVisitor::visit( SubscriptionData::SubscriptionData(std::shared_ptr data, SubscriptionName&& field, response::Value arguments, Directives fieldDirectives, peg::ast&& query, - std::string&& operationName, SubscriptionCallback&& callback, const peg::ast_node& selection) + std::string&& operationName, SubscriptionCallbackOrVisitor&& callback, + const peg::ast_node& selection) : data(std::move(data)) , field(std::move(field)) , arguments(std::move(arguments)) @@ -2154,6 +2158,15 @@ std::pair Request::findOperationDefiniti } response::AwaitableValue Request::resolve(RequestResolveParams params) const +{ + auto visitor = std::make_shared(); + + co_await visit(std::move(params), std::make_shared(visitor)); + co_return visitor->document(); +} + +AwaitableVisit Request::visit( + RequestResolveParams params, const std::shared_ptr& resolverVisitor) const { try { @@ -2210,16 +2223,13 @@ response::AwaitableValue Request::resolve(RequestResolveParams params) const co_await params.launch; operationVisitor.visit(operationType, *operationDefinition); - co_return (co_await operationVisitor.getValue()).toValue(); + (co_await operationVisitor.getValue()).visit(resolverVisitor); } catch (schema_exception& ex) { - response::Value document(response::Type::Map); + ResolverResult document { {}, ex.getStructuredErrors() }; - document.emplace_back(std::string { strData }, response::Value()); - document.emplace_back(std::string { strErrors }, ex.getErrors()); - - co_return std::move(document); + std::move(document).visit(resolverVisitor); } } @@ -2380,26 +2390,42 @@ AwaitableDeliver Request::deliver(RequestDeliverParams params) const params.launch, }; - response::Value document { response::Type::Map }; + ResolverResult document {}; try { co_await params.launch; - auto result = co_await optionalOrDefaultSubscription->resolve(selectionSetParams, + document = co_await optionalOrDefaultSubscription->resolve(selectionSetParams, registration->selection, registration->data->fragments, registration->data->variables); - - document = std::move(result).toValue(); } catch (schema_exception& ex) { - document.emplace_back(std::string { strData }, response::Value()); - document.emplace_back(std::string { strErrors }, ex.getErrors()); + document.errors.splice(document.errors.end(), ex.getStructuredErrors()); } - registration->callback(std::move(document)); + std::visit( + [result = std::move(document)](const auto& callback) mutable { + using callback_type = std::decay_t; + + if constexpr (std::is_same_v) + { + auto visitor = std::make_shared(); + + (std::move(result)).visit(std::make_shared(visitor)); + + callback(visitor->document()); + } + else if constexpr (std::is_same_v) + { + auto visitor = callback(); + + (std::move(result)).visit(visitor); + } + }, + registration->callback); } co_return; From bc364ed60fef3ce72c30f4cddd8ab4d90bd5425c Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 13 Oct 2024 12:14:49 -0700 Subject: [PATCH 090/123] chore: refactor service::ResolverVisitor to response::ValueVisitor --- include/graphqlservice/GraphQLResponse.h | 289 ++++++++++- include/graphqlservice/GraphQLService.h | 284 +---------- include/graphqlservice/Response.ixx | 4 + include/graphqlservice/Service.ixx | 4 - samples/learn/schema/StarWarsSharedTypes.cpp | 2 +- samples/proxy/schema/ProxySharedTypes.cpp | 2 +- .../nointrospection/TodaySharedTypes.cpp | 2 +- samples/today/schema/TodaySharedTypes.cpp | 2 +- .../schema/ValidationSharedTypes.cpp | 4 +- src/GraphQLResponse.cpp | 386 ++++++++++++++- src/GraphQLService.cpp | 453 ++---------------- src/SchemaGenerator.cpp | 4 +- .../IntrospectionSharedTypes.cpp | 4 +- 13 files changed, 730 insertions(+), 710 deletions(-) diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index f155c04f..c4bd7765 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -6,13 +6,14 @@ #ifndef GRAPHQLRESPONSE_H #define GRAPHQLRESPONSE_H -#include "internal/DllExports.h" #include "internal/Awaitable.h" +#include "internal/DllExports.h" #include #include #include #include +#include #include #include #include @@ -375,6 +376,292 @@ GRAPHQLRESPONSE_EXPORT IdType Value::release(); using AwaitableValue = internal::Awaitable; +// Type-erased visitor for alternate representations of Value. +class [[nodiscard("unnecessary construction")]] ValueVisitor final + : public std::enable_shared_from_this +{ +private: + struct Concept + { + virtual ~Concept() = default; + + virtual void add_value(std::shared_ptr&& value) = 0; + + virtual void reserve(std::size_t count) = 0; + + virtual void start_object() = 0; + virtual void add_member(std::string&& key) = 0; + virtual void end_object() = 0; + + virtual void start_array() = 0; + virtual void end_array() = 0; + + virtual void add_null() = 0; + virtual void add_string(std::string&& value) = 0; + virtual void add_enum(std::string&& value) = 0; + virtual void add_id(IdType&& value) = 0; + virtual void add_bool(bool value) = 0; + virtual void add_int(int value) = 0; + virtual void add_float(double value) = 0; + + virtual void complete() = 0; + }; + + template + struct Model : Concept + { + explicit Model(std::shared_ptr pimpl) noexcept + : _pimpl { std::move(pimpl) } + { + } + + void add_value(std::shared_ptr&& value) final + { + _pimpl->add_value(std::move(value)); + } + + void reserve(std::size_t count) final + { + _pimpl->reserve(count); + } + + void start_object() final + { + _pimpl->start_object(); + } + + void add_member(std::string&& key) final + { + _pimpl->add_member(std::move(key)); + } + + void end_object() final + { + _pimpl->end_object(); + } + + void start_array() final + { + _pimpl->start_array(); + } + + void end_array() final + { + _pimpl->end_array(); + } + + void add_null() final + { + _pimpl->add_null(); + } + + void add_string(std::string&& value) final + { + _pimpl->add_string(std::move(value)); + } + + void add_enum(std::string&& value) final + { + _pimpl->add_enum(std::move(value)); + } + + void add_id(IdType&& value) final + { + _pimpl->add_id(std::move(value)); + } + + void add_bool(bool value) final + { + _pimpl->add_bool(value); + } + + void add_int(int value) final + { + _pimpl->add_int(value); + } + + void add_float(double value) final + { + _pimpl->add_float(value); + } + + void complete() final + { + _pimpl->complete(); + } + + private: + std::shared_ptr _pimpl; + }; + + const std::shared_ptr _concept; + +public: + template + ValueVisitor(std::shared_ptr writer) noexcept + : _concept { std::static_pointer_cast( + std::make_shared>(std::move(writer))) } + { + } + + GRAPHQLRESPONSE_EXPORT void add_value(std::shared_ptr&& value); + + GRAPHQLRESPONSE_EXPORT void reserve(std::size_t count); + + GRAPHQLRESPONSE_EXPORT void start_object(); + GRAPHQLRESPONSE_EXPORT void add_member(std::string&& key); + GRAPHQLRESPONSE_EXPORT void end_object(); + + GRAPHQLRESPONSE_EXPORT void start_array(); + GRAPHQLRESPONSE_EXPORT void end_array(); + + GRAPHQLRESPONSE_EXPORT void add_null(); + GRAPHQLRESPONSE_EXPORT void add_string(std::string&& value); + GRAPHQLRESPONSE_EXPORT void add_enum(std::string&& value); + GRAPHQLRESPONSE_EXPORT void add_id(IdType&& value); + GRAPHQLRESPONSE_EXPORT void add_bool(bool value); + GRAPHQLRESPONSE_EXPORT void add_int(int value); + GRAPHQLRESPONSE_EXPORT void add_float(double value); + + GRAPHQLRESPONSE_EXPORT void complete(); +}; + +// Pending token for ValueVisitor. +struct [[nodiscard("unnecessary construction")]] ValueToken +{ + using OpaqueValue = std::shared_ptr; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(OpaqueValue&& value); + + struct Reserve + { + std::size_t capacity; + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(Reserve&& value); + + struct StartObject + { + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(StartObject&& value); + + struct AddMember + { + std::string key; + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(AddMember&& value); + + struct EndObject + { + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(EndObject&& value); + + struct StartArray + { + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(StartArray&& value); + + struct EndArray + { + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(EndArray&& value); + + struct NullValue + { + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(NullValue&& value); + + struct StringValue + { + std::string value; + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(StringValue&& value); + + struct EnumValue + { + std::string value; + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(EnumValue&& value); + + struct IdValue + { + IdType value; + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(IdValue&& value); + + struct BoolValue + { + bool value; + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(BoolValue&& value); + + struct IntValue + { + int value; + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(IntValue&& value); + + struct FloatValue + { + double value; + }; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(FloatValue&& value); + + GRAPHQLRESPONSE_EXPORT void visit(const std::shared_ptr& visitor) &&; + +private: + using variant_type = + std::variant; + + variant_type _value; +}; + +class [[nodiscard("unnecessary construction")]] ValueTokenStream final +{ +public: + ValueTokenStream() noexcept = default; + ~ValueTokenStream() = default; + + ValueTokenStream(ValueTokenStream&&) noexcept = default; + ValueTokenStream& operator=(ValueTokenStream&&) noexcept = default; + + ValueTokenStream(const ValueTokenStream&) = delete; + ValueTokenStream& operator=(const ValueTokenStream&) = delete; + + template + ValueTokenStream(TArg&& arg) + : _tokens { ValueToken { std::forward(arg) } } + { + } + + template + void push_back(TArg&& arg) + { + _tokens.push_back(ValueToken { std::forward(arg) }); + } + + GRAPHQLRESPONSE_EXPORT void append(ValueTokenStream&& other); + + GRAPHQLRESPONSE_EXPORT void visit(const std::shared_ptr& visitor) &&; + GRAPHQLRESPONSE_EXPORT Value value() &&; + +private: + std::list _tokens; +}; + class [[nodiscard("unnecessary construction")]] Writer final { private: diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index fd3bbebe..95cba892 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -487,165 +487,6 @@ class [[nodiscard("unnecessary construction")]] AwaitableObject std::variant> _value; }; -// Type-erased visitor for resolvers. -class [[nodiscard("unnecessary construction")]] ResolverVisitor final - : public std::enable_shared_from_this -{ -private: - struct Concept - { - virtual ~Concept() = default; - - virtual void add_value(std::shared_ptr&& value) = 0; - - virtual void reserve(std::size_t count) = 0; - - virtual void start_object() = 0; - virtual void add_member(std::string&& key) = 0; - virtual void end_object() = 0; - - virtual void start_array() = 0; - virtual void end_array() = 0; - - virtual void add_null() = 0; - virtual void add_string(std::string&& value) = 0; - virtual void add_enum(std::string&& value) = 0; - virtual void add_id(response::IdType&& value) = 0; - virtual void add_bool(bool value) = 0; - virtual void add_int(int value) = 0; - virtual void add_float(double value) = 0; - - virtual void add_error(schema_error&& error) = 0; - - virtual void complete() = 0; - }; - - template - struct Model : Concept - { - explicit Model(std::shared_ptr pimpl) noexcept - : _pimpl { std::move(pimpl) } - { - } - - void add_value(std::shared_ptr&& value) final - { - _pimpl->add_value(std::move(value)); - } - - void reserve(std::size_t count) final - { - _pimpl->reserve(count); - } - - void start_object() final - { - _pimpl->start_object(); - } - - void add_member(std::string&& key) final - { - _pimpl->add_member(std::move(key)); - } - - void end_object() final - { - _pimpl->end_object(); - } - - void start_array() final - { - _pimpl->start_array(); - } - - void end_array() final - { - _pimpl->end_array(); - } - - void add_null() final - { - _pimpl->add_null(); - } - - void add_string(std::string&& value) final - { - _pimpl->add_string(std::move(value)); - } - - void add_enum(std::string&& value) final - { - _pimpl->add_enum(std::move(value)); - } - - void add_id(response::IdType&& value) final - { - _pimpl->add_id(std::move(value)); - } - - void add_bool(bool value) final - { - _pimpl->add_bool(value); - } - - void add_int(int value) final - { - _pimpl->add_int(value); - } - - void add_float(double value) final - { - _pimpl->add_float(value); - } - - void add_error(schema_error&& error) final - { - _pimpl->add_error(std::move(error)); - } - - void complete() final - { - _pimpl->complete(); - } - - private: - std::shared_ptr _pimpl; - }; - - const std::shared_ptr _concept; - -public: - template - ResolverVisitor(std::shared_ptr writer) noexcept - : _concept { std::static_pointer_cast( - std::make_shared>(std::move(writer))) } - { - } - - GRAPHQLSERVICE_EXPORT void add_value(std::shared_ptr&& value); - - GRAPHQLSERVICE_EXPORT void reserve(std::size_t count); - - GRAPHQLSERVICE_EXPORT void start_object(); - GRAPHQLSERVICE_EXPORT void add_member(std::string&& key); - GRAPHQLSERVICE_EXPORT void end_object(); - - GRAPHQLSERVICE_EXPORT void start_array(); - GRAPHQLSERVICE_EXPORT void end_array(); - - GRAPHQLSERVICE_EXPORT void add_null(); - GRAPHQLSERVICE_EXPORT void add_string(std::string&& value); - GRAPHQLSERVICE_EXPORT void add_enum(std::string&& value); - GRAPHQLSERVICE_EXPORT void add_id(response::IdType&& value); - GRAPHQLSERVICE_EXPORT void add_bool(bool value); - GRAPHQLSERVICE_EXPORT void add_int(int value); - GRAPHQLSERVICE_EXPORT void add_float(double value); - - GRAPHQLSERVICE_EXPORT void add_error(schema_error&& error); - - GRAPHQLSERVICE_EXPORT void complete(); -}; - // Fragments are referenced by name and have a single type condition (except for inline // fragments, where the type condition is common but optional). They contain a set of fields // (with optional aliases and sub-selections) and potentially references to other fragments. @@ -694,103 +535,13 @@ struct [[nodiscard("unnecessary construction")]] ResolverParams : SelectionSetPa const response::Value& variables; }; -// Pending token for ResolverVisitor. -struct [[nodiscard("unnecessary construction")]] ResultToken -{ - using OpaqueValue = std::shared_ptr; - - struct Reserve - { - std::size_t capacity; - }; - - struct StartObject - { - }; - - struct AddMember - { - std::string key; - }; - - struct EndObject - { - }; - - struct StartArray - { - }; - - struct EndArray - { - }; - - struct NullValue - { - }; - - struct StringValue - { - std::string value; - }; - - struct EnumValue - { - std::string value; - }; - - struct IdValue - { - response::IdType value; - }; - - struct BoolValue - { - bool value; - }; - - struct IntValue - { - int value; - }; - - struct FloatValue - { - double value; - }; - - GRAPHQLSERVICE_EXPORT explicit ResultToken(OpaqueValue&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(Reserve&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(StartObject&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(AddMember&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(EndObject&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(StartArray&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(EndArray&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(NullValue&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(StringValue&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(EnumValue&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(IdValue&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(BoolValue&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(IntValue&& value); - GRAPHQLSERVICE_EXPORT explicit ResultToken(FloatValue&& value); - - GRAPHQLSERVICE_EXPORT void visit(const std::shared_ptr& visitor) &&; - -private: - using variant_type = - std::variant; - - variant_type _value; -}; - // Propagate data and errors together without bundling them into a response::Value struct until // we're ready to return from the top level Operation. struct [[nodiscard("unnecessary construction")]] ResolverResult { - GRAPHQLSERVICE_EXPORT void visit(const std::shared_ptr& visitor) &&; + [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT response::Value document() &&; - std::list data {}; + response::ValueTokenStream data {}; std::list errors {}; }; @@ -1270,7 +1021,7 @@ struct ModifiedResult if (!awaitedResult) { - co_return ResolverResult { { ResultToken { ResultToken::NullValue {} } } }; + co_return ResolverResult { { response::ValueToken::NullValue {} } }; } auto modifiedResult = @@ -1297,8 +1048,8 @@ struct ModifiedResult if (value) { ModifiedResult::validateScalar(*value); - co_return ResolverResult { { ResultToken { - ResultToken::OpaqueValue { std::shared_ptr { std::move(value) } } } } }; + co_return ResolverResult { { response::ValueToken::OpaqueValue { + std::shared_ptr { std::move(value) } } } }; } } @@ -1311,7 +1062,7 @@ struct ModifiedResult if (!awaitedResult) { - co_return ResolverResult { { ResultToken { ResultToken::NullValue {} } } }; + co_return ResolverResult { { response::ValueToken::NullValue {} } }; } auto modifiedResult = co_await ModifiedResult::convert(std::move(*awaitedResult), @@ -1334,8 +1085,8 @@ struct ModifiedResult if (value) { ModifiedResult::validateScalar(*value); - co_return ResolverResult { { ResultToken { - ResultToken::OpaqueValue { std::shared_ptr { std::move(value) } } } } }; + co_return ResolverResult { { response::ValueToken::OpaqueValue { + std::shared_ptr { std::move(value) } } } }; } } @@ -1381,8 +1132,8 @@ struct ModifiedResult ResolverResult document; - document.data.push_back(ResultToken { ResultToken::StartArray {} }); - document.data.push_back(ResultToken { ResultToken::Reserve { children.size() } }); + document.data.push_back(response::ValueToken::StartArray {}); + document.data.push_back(response::ValueToken::Reserve { children.size() }); std::get(params.errorPath->segment) = 0; for (auto& child : children) @@ -1393,7 +1144,7 @@ struct ModifiedResult auto value = co_await std::move(child); - document.data.splice(document.data.end(), std::move(value.data)); + document.data.append(std::move(value.data)); if (!value.errors.empty()) { @@ -1423,7 +1174,7 @@ struct ModifiedResult ++std::get(params.errorPath->segment); } - document.data.push_back(ResultToken { ResultToken::EndArray {} }); + document.data.push_back(response::ValueToken::EndArray {}); co_return document; } @@ -1480,8 +1231,8 @@ struct ModifiedResult if (value) { Result::validateScalar(*value); - co_return ResolverResult { { ResultToken { - ResultToken::OpaqueValue { std::shared_ptr { std::move(value) } } } } }; + co_return ResolverResult { { response::ValueToken::OpaqueValue { + std::shared_ptr { std::move(value) } } } }; } auto pendingResolver = std::move(resolver); @@ -1534,14 +1285,13 @@ using ObjectResult = ModifiedResult; // Subscription callbacks receive the response::Value representing the result of evaluating the // SelectionSet against the payload. using SubscriptionCallback = std::function; -using SubscriptionVisitor = std::function()>; +using SubscriptionVisitor = std::function; using SubscriptionCallbackOrVisitor = std::variant; // Subscriptions are stored in maps using these keys. using SubscriptionKey = std::size_t; using SubscriptionName = std::string; -using AwaitableVisit = internal::Awaitable; using AwaitableSubscribe = internal::Awaitable; using AwaitableUnsubscribe = internal::Awaitable; using AwaitableDeliver = internal::Awaitable; @@ -1699,8 +1449,8 @@ class [[nodiscard("unnecessary construction")]] Request [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT response::AwaitableValue resolve( RequestResolveParams params) const; - [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT AwaitableVisit visit( - RequestResolveParams params, const std::shared_ptr& resolverVisitor) const; + [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT AwaitableResolver visit( + RequestResolveParams params) const; [[nodiscard("leaked subscription")]] GRAPHQLSERVICE_EXPORT AwaitableSubscribe subscribe( RequestSubscribeParams params); [[nodiscard("potentially leaked subscription")]] GRAPHQLSERVICE_EXPORT AwaitableUnsubscribe diff --git a/include/graphqlservice/Response.ixx b/include/graphqlservice/Response.ixx index 5e4160ce..4f83da5d 100644 --- a/include/graphqlservice/Response.ixx +++ b/include/graphqlservice/Response.ixx @@ -28,6 +28,10 @@ using response::ValueTypeTraits; using response::Value; using response::AwaitableValue; +using response::ValueVisitor; +using response::ValueToken; +using response::ValueTokenStream; + using response::Writer; // clang-format on diff --git a/include/graphqlservice/Service.ixx b/include/graphqlservice/Service.ixx index 3e62fdeb..63cc8119 100644 --- a/include/graphqlservice/Service.ixx +++ b/include/graphqlservice/Service.ixx @@ -66,13 +66,10 @@ using service::FieldParams; using service::AwaitableScalar; using service::AwaitableObject; -using service::ResolverVisitor; - using service::Fragment; using service::FragmentMap; using service::ResolverParams; -using service::ResultToken; using service::ResolverResult; using service::AwaitableResolver; using service::Resolver; @@ -108,7 +105,6 @@ using service::SubscriptionCallbackOrVisitor; using service::SubscriptionKey; using service::SubscriptionName; -using service::AwaitableVisit; using service::AwaitableSubscribe; using service::AwaitableUnsubscribe; using service::AwaitableDeliver; diff --git a/samples/learn/schema/StarWarsSharedTypes.cpp b/samples/learn/schema/StarWarsSharedTypes.cpp index 03051730..b1034fe2 100644 --- a/samples/learn/schema/StarWarsSharedTypes.cpp +++ b/samples/learn/schema/StarWarsSharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::AwaitableSca return ModifiedResult::resolve(std::move(result), std::move(params), [](learn::Episode value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesEpisode[static_cast(value)] } } } } }; + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesEpisode[static_cast(value)] } } } }; }); } diff --git a/samples/proxy/schema/ProxySharedTypes.cpp b/samples/proxy/schema/ProxySharedTypes.cpp index b04e6076..8fba4aa3 100644 --- a/samples/proxy/schema/ProxySharedTypes.cpp +++ b/samples/proxy/schema/ProxySharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::Awaita return ModifiedResult::resolve(std::move(result), std::move(params), [](proxy::OperationType value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesOperationType[static_cast(value)] } } } } }; + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesOperationType[static_cast(value)] } } } }; }); } diff --git a/samples/today/nointrospection/TodaySharedTypes.cpp b/samples/today/nointrospection/TodaySharedTypes.cpp index da5e03da..2d9d50ca 100644 --- a/samples/today/nointrospection/TodaySharedTypes.cpp +++ b/samples/today/nointrospection/TodaySharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::AwaitableS return ModifiedResult::resolve(std::move(result), std::move(params), [](today::TaskState value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesTaskState[static_cast(value)] } } } } }; + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesTaskState[static_cast(value)] } } } }; }); } diff --git a/samples/today/schema/TodaySharedTypes.cpp b/samples/today/schema/TodaySharedTypes.cpp index da5e03da..2d9d50ca 100644 --- a/samples/today/schema/TodaySharedTypes.cpp +++ b/samples/today/schema/TodaySharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::AwaitableS return ModifiedResult::resolve(std::move(result), std::move(params), [](today::TaskState value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesTaskState[static_cast(value)] } } } } }; + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesTaskState[static_cast(value)] } } } }; }); } diff --git a/samples/validation/schema/ValidationSharedTypes.cpp b/samples/validation/schema/ValidationSharedTypes.cpp index 84837b35..4db548fa 100644 --- a/samples/validation/schema/ValidationSharedTypes.cpp +++ b/samples/validation/schema/ValidationSharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::Awai return ModifiedResult::resolve(std::move(result), std::move(params), [](validation::DogCommand value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesDogCommand[static_cast(value)] } } } } }; + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesDogCommand[static_cast(value)] } } } }; }); } @@ -102,7 +102,7 @@ service::AwaitableResolver Result::convert(service::Awai return ModifiedResult::resolve(std::move(result), std::move(params), [](validation::CatCommand value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesCatCommand[static_cast(value)] } } } } }; + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesCatCommand[static_cast(value)] } } } }; }); } diff --git a/src/GraphQLResponse.cpp b/src/GraphQLResponse.cpp index d04a3bf3..984a2034 100644 --- a/src/GraphQLResponse.cpp +++ b/src/GraphQLResponse.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -100,9 +101,9 @@ bool IdType::operator==(const IdType& rhs) const noexcept return (std::holds_alternative(_data) ? internal::Base64::compareBase64(std::get(_data), - std::get(rhs._data)) + std::get(rhs._data)) : internal::Base64::compareBase64(std::get(rhs._data), - std::get(_data))) + std::get(_data))) == internal::Base64::Comparison::EqualTo; } @@ -145,7 +146,7 @@ bool IdType::operator<(const IdType& rhs) const noexcept return (std::holds_alternative(_data) ? (internal::Base64::compareBase64(std::get(_data), std::get(rhs._data)) - < internal::Base64::Comparison::EqualTo) + < internal::Base64::Comparison::EqualTo) : (internal::Base64::compareBase64(std::get(rhs._data), std::get(_data))) > internal::Base64::Comparison::EqualTo); @@ -1446,6 +1447,385 @@ const Value& Value::operator[](std::size_t index) const return std::get(typeData).at(index); } +void ValueVisitor::add_value(std::shared_ptr&& value) +{ + _concept->add_value(std::move(value)); +} + +void ValueVisitor::reserve(std::size_t count) +{ + _concept->reserve(count); +} + +void ValueVisitor::start_object() +{ + _concept->start_object(); +} + +void ValueVisitor::add_member(std::string&& key) +{ + _concept->add_member(std::move(key)); +} + +void ValueVisitor::end_object() +{ + _concept->end_object(); +} + +void ValueVisitor::start_array() +{ + _concept->start_array(); +} + +void ValueVisitor::end_array() +{ + _concept->end_array(); +} + +void ValueVisitor::add_null() +{ + _concept->add_null(); +} + +void ValueVisitor::add_string(std::string&& value) +{ + _concept->add_string(std::move(value)); +} + +void ValueVisitor::add_enum(std::string&& value) +{ + _concept->add_enum(std::move(value)); +} + +void ValueVisitor::add_id(response::IdType&& value) +{ + _concept->add_id(std::move(value)); +} + +void ValueVisitor::add_bool(bool value) +{ + _concept->add_bool(value); +} + +void ValueVisitor::add_int(int value) +{ + _concept->add_int(value); +} + +void ValueVisitor::add_float(double value) +{ + _concept->add_float(value); +} + +void ValueVisitor::complete() +{ + _concept->complete(); +} + +ValueToken::ValueToken(OpaqueValue&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(Reserve&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(StartObject&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(AddMember&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(EndObject&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(StartArray&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(EndArray&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(NullValue&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(StringValue&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(EnumValue&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(IdValue&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(BoolValue&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(IntValue&& value) + : _value { std::move(value) } +{ +} + +ValueToken::ValueToken(FloatValue&& value) + : _value { std::move(value) } +{ +} + +void ValueToken::visit(const std::shared_ptr& visitor) && +{ + std::visit( + [&visitor](auto&& value) { + using value_type = std::decay_t; + + if constexpr (std::is_same_v) + { + visitor->add_value(std::move(value)); + } + else if constexpr (std::is_same_v) + { + visitor->reserve(value.capacity); + } + else if constexpr (std::is_same_v) + { + visitor->start_object(); + } + else if constexpr (std::is_same_v) + { + visitor->add_member(std::move(value.key)); + } + else if constexpr (std::is_same_v) + { + visitor->end_object(); + } + else if constexpr (std::is_same_v) + { + visitor->start_array(); + } + else if constexpr (std::is_same_v) + { + visitor->end_array(); + } + else if constexpr (std::is_same_v) + { + visitor->add_null(); + } + else if constexpr (std::is_same_v) + { + visitor->add_string(std::move(value.value)); + } + else if constexpr (std::is_same_v) + { + visitor->add_enum(std::move(value.value)); + } + else if constexpr (std::is_same_v) + { + visitor->add_id(std::move(value.value)); + } + else if constexpr (std::is_same_v) + { + visitor->add_bool(value.value); + } + else if constexpr (std::is_same_v) + { + visitor->add_int(value.value); + } + else if constexpr (std::is_same_v) + { + visitor->add_float(value.value); + } + }, + std::move(_value)); +} + +class ValueTokenStreamVisitor +{ +public: + void add_value(std::shared_ptr&& value); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Value value(); + +private: + void add_value(Value&& value); + + Value _result {}; + std::stack _values {}; + std::stack _keys {}; +}; + +void ValueTokenStreamVisitor::add_value(std::shared_ptr&& value) +{ + add_value(Value { std::move(value) }); +} + +void ValueTokenStreamVisitor::reserve(std::size_t count) +{ + _values.top().reserve(count); +} + +void ValueTokenStreamVisitor::start_object() +{ + _values.push(Value { response::Type::Map }); +} + +void ValueTokenStreamVisitor::add_member(std::string&& key) +{ + _keys.push(std::move(key)); +} + +void ValueTokenStreamVisitor::end_object() +{ + auto value = std::move(_values.top()); + + _values.pop(); + add_value(std::move(value)); +} + +void ValueTokenStreamVisitor::start_array() +{ + _values.push(Value { response::Type::List }); +} + +void ValueTokenStreamVisitor::end_array() +{ + auto value = std::move(_values.top()); + + _values.pop(); + add_value(std::move(value)); +} + +void ValueTokenStreamVisitor::add_null() +{ + add_value(Value {}); +} + +void ValueTokenStreamVisitor::add_string(std::string&& value) +{ + add_value(Value { std::move(value) }); +} + +void ValueTokenStreamVisitor::add_enum(std::string&& value) +{ + Value enumValue { response::Type::EnumValue }; + + enumValue.set(std::move(value)); + add_value(std::move(enumValue)); +} + +void ValueTokenStreamVisitor::add_id(response::IdType&& value) +{ + add_value(Value { std::move(value) }); +} + +void ValueTokenStreamVisitor::add_bool(bool value) +{ + add_value(Value { std::move(value) }); +} + +void ValueTokenStreamVisitor::add_int(int value) +{ + add_value(Value { std::move(value) }); +} + +void ValueTokenStreamVisitor::add_float(double value) +{ + add_value(Value { std::move(value) }); +} + +void ValueTokenStreamVisitor::complete() +{ +} + +Value ValueTokenStreamVisitor::value() +{ + auto value = std::move(_result); + + return value; +} + +void ValueTokenStreamVisitor::add_value(Value&& value) +{ + if (_values.empty()) + { + _result = std::move(value); + return; + } + + switch (_values.top().type()) + { + case response::Type::Map: + _values.top().emplace_back(std::move(_keys.top()), std::move(value)); + _keys.pop(); + break; + + case response::Type::List: + _values.top().emplace_back(std::move(value)); + break; + + default: + throw std::logic_error("Invalid call to Value::emplace_back"); + break; + } +} + +void ValueTokenStream::append(ValueTokenStream&& other) +{ + _tokens.splice(_tokens.end(), std::move(other._tokens)); +} + +void ValueTokenStream::visit(const std::shared_ptr& visitor) && +{ + for (auto& token : _tokens) + { + std::move(token).visit(visitor); + } + + visitor->complete(); +} + +Value ValueTokenStream::value() && +{ + auto visitor = std::make_shared(); + + std::move(*this).visit(std::make_shared(visitor)); + + return visitor->value(); +} + void Writer::write(Value response) const { switch (response.type()) diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index f711502b..b7df2161 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -274,86 +274,6 @@ void await_async::await_resume() const _pimpl->await_resume(); } -void ResolverVisitor::add_value(std::shared_ptr&& value) -{ - _concept->add_value(std::move(value)); -} - -void ResolverVisitor::reserve(std::size_t count) -{ - _concept->reserve(count); -} - -void ResolverVisitor::start_object() -{ - _concept->start_object(); -} - -void ResolverVisitor::add_member(std::string&& key) -{ - _concept->add_member(std::move(key)); -} - -void ResolverVisitor::end_object() -{ - _concept->end_object(); -} - -void ResolverVisitor::start_array() -{ - _concept->start_array(); -} - -void ResolverVisitor::end_array() -{ - _concept->end_array(); -} - -void ResolverVisitor::add_null() -{ - _concept->add_null(); -} - -void ResolverVisitor::add_string(std::string&& value) -{ - _concept->add_string(std::move(value)); -} - -void ResolverVisitor::add_enum(std::string&& value) -{ - _concept->add_enum(std::move(value)); -} - -void ResolverVisitor::add_id(response::IdType&& value) -{ - _concept->add_id(std::move(value)); -} - -void ResolverVisitor::add_bool(bool value) -{ - _concept->add_bool(value); -} - -void ResolverVisitor::add_int(int value) -{ - _concept->add_int(value); -} - -void ResolverVisitor::add_float(double value) -{ - _concept->add_float(value); -} - -void ResolverVisitor::add_error(schema_error&& error) -{ - _concept->add_error(std::move(error)); -} - -void ResolverVisitor::complete() -{ - _concept->complete(); -} - FieldParams::FieldParams(SelectionSetParams&& selectionSetParams, Directives directives) : SelectionSetParams(std::move(selectionSetParams)) , fieldDirectives(std::move(directives)) @@ -701,321 +621,20 @@ schema_location ResolverParams::getLocation() const return { position.line, position.column }; } -ResultToken::ResultToken(OpaqueValue&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(Reserve&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(StartObject&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(AddMember&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(EndObject&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(StartArray&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(EndArray&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(NullValue&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(StringValue&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(EnumValue&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(IdValue&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(BoolValue&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(IntValue&& value) - : _value { std::move(value) } -{ -} - -ResultToken::ResultToken(FloatValue&& value) - : _value { std::move(value) } -{ -} - -void ResultToken::visit(const std::shared_ptr& visitor) && -{ - std::visit( - [&visitor](auto&& value) { - using value_type = std::decay_t; - - if constexpr (std::is_same_v) - { - visitor->add_value(std::move(value)); - } - else if constexpr (std::is_same_v) - { - visitor->reserve(value.capacity); - } - else if constexpr (std::is_same_v) - { - visitor->start_object(); - } - else if constexpr (std::is_same_v) - { - visitor->add_member(std::move(value.key)); - } - else if constexpr (std::is_same_v) - { - visitor->end_object(); - } - else if constexpr (std::is_same_v) - { - visitor->start_array(); - } - else if constexpr (std::is_same_v) - { - visitor->end_array(); - } - else if constexpr (std::is_same_v) - { - visitor->add_null(); - } - else if constexpr (std::is_same_v) - { - visitor->add_string(std::move(value.value)); - } - else if constexpr (std::is_same_v) - { - visitor->add_enum(std::move(value.value)); - } - else if constexpr (std::is_same_v) - { - visitor->add_id(std::move(value.value)); - } - else if constexpr (std::is_same_v) - { - visitor->add_bool(value.value); - } - else if constexpr (std::is_same_v) - { - visitor->add_int(value.value); - } - else if constexpr (std::is_same_v) - { - visitor->add_float(value.value); - } - }, - std::move(_value)); -} - -class ResolverResultVisitor -{ -public: - explicit ResolverResultVisitor() noexcept; - - void add_value(std::shared_ptr&& value); - void reserve(std::size_t count); - void start_object(); - void add_member(std::string&& key); - void end_object(); - void start_array(); - void end_array(); - void add_null(); - void add_string(std::string&& value); - void add_enum(std::string&& value); - void add_id(response::IdType&& value); - void add_bool(bool value); - void add_int(int value); - void add_float(double value); - void add_error(schema_error&& error); - void complete(); - - response::Value document(); - -private: - void add_value(response::Value&& value); - - response::Value _data {}; - std::list _errors {}; - std::stack _values {}; - std::stack _keys {}; -}; - -ResolverResultVisitor::ResolverResultVisitor() noexcept -{ -} - -void ResolverResultVisitor::add_value(std::shared_ptr&& value) -{ - add_value(response::Value { std::move(value) }); -} - -void ResolverResultVisitor::reserve(std::size_t count) -{ - _values.top().reserve(count); -} - -void ResolverResultVisitor::start_object() -{ - _values.push(response::Value { response::Type::Map }); -} - -void ResolverResultVisitor::add_member(std::string&& key) -{ - _keys.push(std::move(key)); -} - -void ResolverResultVisitor::end_object() -{ - auto value = std::move(_values.top()); - - _values.pop(); - add_value(std::move(value)); -} - -void ResolverResultVisitor::start_array() -{ - _values.push(response::Value { response::Type::List }); -} - -void ResolverResultVisitor::end_array() -{ - auto value = std::move(_values.top()); - - _values.pop(); - add_value(std::move(value)); -} - -void ResolverResultVisitor::add_null() -{ - add_value(response::Value {}); -} - -void ResolverResultVisitor::add_string(std::string&& value) -{ - add_value(response::Value { std::move(value) }); -} - -void ResolverResultVisitor::add_enum(std::string&& value) -{ - response::Value enumValue { response::Type::EnumValue }; - - enumValue.set(std::move(value)); - add_value(std::move(enumValue)); -} - -void ResolverResultVisitor::add_id(response::IdType&& value) -{ - add_value(response::Value { std::move(value) }); -} - -void ResolverResultVisitor::add_bool(bool value) -{ - add_value(response::Value { std::move(value) }); -} - -void ResolverResultVisitor::add_int(int value) -{ - add_value(response::Value { std::move(value) }); -} - -void ResolverResultVisitor::add_float(double value) -{ - add_value(response::Value { std::move(value) }); -} - -void ResolverResultVisitor::add_error(schema_error&& error) -{ - _errors.push_back(std::move(error)); -} - -void ResolverResultVisitor::complete() -{ -} - -response::Value ResolverResultVisitor::document() +response::Value ResolverResult::document() && { response::Value document { response::Type::Map }; - document.emplace_back(std::string { strData }, std::move(_data)); + document.emplace_back(std::string { strData }, std::move(data).value()); - if (!_errors.empty()) + if (!errors.empty()) { - document.emplace_back(std::string { strErrors }, buildErrorValues(std::move(_errors))); + document.emplace_back(std::string { strErrors }, buildErrorValues(std::move(errors))); } return document; } -void ResolverResultVisitor::add_value(response::Value&& value) -{ - if (_values.empty()) - { - _data = std::move(value); - return; - } - - switch (_values.top().type()) - { - case response::Type::Map: - _values.top().emplace_back(std::move(_keys.top()), std::move(value)); - _keys.pop(); - break; - - case response::Type::List: - _values.top().emplace_back(std::move(value)); - break; - - default: - throw std::logic_error("Invalid call to Value::emplace_back"); - break; - } -} - -void ResolverResult::visit(const std::shared_ptr& visitor) && -{ - for (auto& token : data) - { - std::move(token).visit(visitor); - } - - for (auto& error : errors) - { - visitor->add_error(std::move(error)); - } - - visitor->complete(); -} - template <> int Argument::convert(const response::Value& value) { @@ -1099,7 +718,7 @@ AwaitableResolver Result::convert(AwaitableScalar result, ResolverPara return ModifiedResult::resolve(std::move(result), std::move(params), [](int&& value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::IntValue { value } } } }; + return ResolverResult { { response::ValueToken::IntValue { value } } }; }); } @@ -1111,7 +730,7 @@ AwaitableResolver Result::convert(AwaitableScalar result, Resolv return ModifiedResult::resolve(std::move(result), std::move(params), [](double&& value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::FloatValue { value } } } }; + return ResolverResult { { response::ValueToken::FloatValue { value } } }; }); } @@ -1124,8 +743,7 @@ AwaitableResolver Result::convert( return ModifiedResult::resolve(std::move(result), std::move(params), [](std::string&& value, const ResolverParams&) { - return ResolverResult { { ResultToken { - ResultToken::StringValue { std::move(value) } } } }; + return ResolverResult { { response::ValueToken::StringValue { std::move(value) } } }; }); } @@ -1137,7 +755,7 @@ AwaitableResolver Result::convert(AwaitableScalar result, ResolverPa return ModifiedResult::resolve(std::move(result), std::move(params), [](bool&& value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::BoolValue { value } } } }; + return ResolverResult { { response::ValueToken::BoolValue { value } } }; }); } @@ -1150,8 +768,8 @@ AwaitableResolver Result::convert( return ModifiedResult::resolve(std::move(result), std::move(params), [](response::Value&& value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::OpaqueValue { - std::make_shared(std::move(value)) } } } }; + return ResolverResult { { response::ValueToken::OpaqueValue { + std::make_shared(std::move(value)) } } }; }); } @@ -1164,7 +782,7 @@ AwaitableResolver Result::convert( return ModifiedResult::resolve(std::move(result), std::move(params), [](response::IdType&& value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::IdValue { std::move(value) } } } }; + return ResolverResult { { response::ValueToken::IdValue { std::move(value) } } }; }); } @@ -1197,7 +815,7 @@ AwaitableResolver Result::convert( if (!awaitedResult) { - co_return ResolverResult { { ResultToken { ResultToken::NullValue {} } } }; + co_return ResolverResult { { response::ValueToken::NullValue {} } }; } auto document = co_await awaitedResult->resolve(params, @@ -1628,8 +1246,8 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, const auto launch = selectionSetParams.launch; ResolverResult document {}; - document.data.push_back(ResultToken { ResultToken::StartObject {} }); - document.data.push_back(ResultToken { ResultToken::Reserve { children.size() } }); + document.data.push_back(response::ValueToken::StartObject {}); + document.data.push_back(response::ValueToken::Reserve { children.size() }); const auto parent = selectionSetParams.errorPath ? std::make_optional(std::cref(*selectionSetParams.errorPath)) @@ -1643,9 +1261,8 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, auto value = co_await std::move(child.result); - document.data.push_back( - ResultToken { ResultToken::AddMember { std::string { child.name } } }); - document.data.splice(document.data.end(), std::move(value.data)); + document.data.push_back(response::ValueToken::AddMember { std::string { child.name } }); + document.data.append(std::move(value.data)); if (!value.errors.empty()) { @@ -1661,9 +1278,8 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, std::ranges::copy(errors, std::back_inserter(document.errors)); } - document.data.push_back( - ResultToken { ResultToken::AddMember { std::string { child.name } } }); - document.data.push_back(ResultToken { ResultToken::NullValue {} }); + document.data.push_back(response::ValueToken::AddMember { std::string { child.name } }); + document.data.push_back(response::ValueToken::NullValue {}); } catch (const std::exception& ex) { @@ -1674,13 +1290,12 @@ AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, document.errors.push_back({ std::move(message), child.location.value_or(schema_location {}), buildErrorPath(std::make_optional(path)) }); - document.data.push_back( - ResultToken { ResultToken::AddMember { std::string { child.name } } }); - document.data.push_back(ResultToken { ResultToken::NullValue {} }); + document.data.push_back(response::ValueToken::AddMember { std::string { child.name } }); + document.data.push_back(response::ValueToken::NullValue {}); } } - document.data.push_back(ResultToken { ResultToken::EndObject {} }); + document.data.push_back(response::ValueToken::EndObject {}); co_return std::move(document); } @@ -1779,7 +1394,7 @@ AwaitableResolver OperationDefinitionVisitor::getValue() { if (!_result) { - co_return ResolverResult { { ResultToken { ResultToken::NullValue {} } } }; + co_return ResolverResult { { response::ValueToken::NullValue {} } }; } auto result = std::move(*_result); @@ -2159,14 +1774,10 @@ std::pair Request::findOperationDefiniti response::AwaitableValue Request::resolve(RequestResolveParams params) const { - auto visitor = std::make_shared(); - - co_await visit(std::move(params), std::make_shared(visitor)); - co_return visitor->document(); + co_return (co_await visit(std::move(params))).document(); } -AwaitableVisit Request::visit( - RequestResolveParams params, const std::shared_ptr& resolverVisitor) const +AwaitableResolver Request::visit(RequestResolveParams params) const { try { @@ -2223,13 +1834,11 @@ AwaitableVisit Request::visit( co_await params.launch; operationVisitor.visit(operationType, *operationDefinition); - (co_await operationVisitor.getValue()).visit(resolverVisitor); + co_return co_await operationVisitor.getValue(); } catch (schema_exception& ex) { - ResolverResult document { {}, ex.getStructuredErrors() }; - - std::move(document).visit(resolverVisitor); + co_return { {}, ex.getStructuredErrors() }; } } @@ -2412,17 +2021,11 @@ AwaitableDeliver Request::deliver(RequestDeliverParams params) const if constexpr (std::is_same_v) { - auto visitor = std::make_shared(); - - (std::move(result)).visit(std::make_shared(visitor)); - - callback(visitor->document()); + callback(std::move(result).document()); } else if constexpr (std::is_same_v) { - auto visitor = callback(); - - (std::move(result)).visit(visitor); + callback(std::move(result)); } }, registration->callback); diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 94980317..38a6d248 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -1685,8 +1685,8 @@ service::AwaitableResolver Result<)cpp" []()cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType << R"cpp( value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_names)cpp" - << enumType.cppType << R"cpp([static_cast(value)] } } } } }; + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_names)cpp" + << enumType.cppType << R"cpp([static_cast(value)] } } } }; }); } diff --git a/src/introspection/IntrospectionSharedTypes.cpp b/src/introspection/IntrospectionSharedTypes.cpp index a4f3f8de..ba9a3e7e 100644 --- a/src/introspection/IntrospectionSharedTypes.cpp +++ b/src/introspection/IntrospectionSharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::Awa return ModifiedResult::resolve(std::move(result), std::move(params), [](introspection::TypeKind value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesTypeKind[static_cast(value)] } } } } }; + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesTypeKind[static_cast(value)] } } } }; }); } @@ -102,7 +102,7 @@ service::AwaitableResolver Result::convert(ser return ModifiedResult::resolve(std::move(result), std::move(params), [](introspection::DirectiveLocation value, const ResolverParams&) { - return ResolverResult { { ResultToken { ResultToken::EnumValue { std::string { s_namesDirectiveLocation[static_cast(value)] } } } } }; + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesDirectiveLocation[static_cast(value)] } } } }; }); } From 0906b2815b8fddb701797aaf19691f185a10ea97 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 16 Oct 2024 18:33:52 -0700 Subject: [PATCH 091/123] feat: generate client ResponseVisitor implementations --- include/ClientGenerator.h | 42 + samples/client/benchmark.cpp | 16 +- samples/client/benchmark/TodayClient.cpp | 347 ++++ samples/client/benchmark/TodayClient.h | 32 + samples/client/benchmark/TodayClient.ixx | 1 + .../client/multiple/MultipleQueriesClient.cpp | 1639 +++++++++++++++- .../client/multiple/MultipleQueriesClient.h | 160 ++ .../client/multiple/MultipleQueriesClient.ixx | 5 + samples/client/mutate/MutateClient.cpp | 302 ++- samples/client/mutate/MutateClient.h | 32 + samples/client/mutate/MutateClient.ixx | 1 + .../client/nestedinput/NestedInputClient.cpp | 236 +++ .../client/nestedinput/NestedInputClient.h | 32 + .../client/nestedinput/NestedInputClient.ixx | 1 + samples/client/query/QueryClient.cpp | 808 +++++++- samples/client/query/QueryClient.h | 32 + samples/client/query/QueryClient.ixx | 1 + samples/client/subscribe/SubscribeClient.cpp | 264 +++ samples/client/subscribe/SubscribeClient.h | 32 + samples/client/subscribe/SubscribeClient.ixx | 1 + samples/proxy/query/ProxyClient.cpp | 259 ++- samples/proxy/query/ProxyClient.h | 32 + samples/proxy/query/ProxyClient.ixx | 1 + src/ClientGenerator.cpp | 1701 ++++++++++++++++- 24 files changed, 5913 insertions(+), 64 deletions(-) diff --git a/include/ClientGenerator.h b/include/ClientGenerator.h index 4070a12f..702184dd 100644 --- a/include/ClientGenerator.h +++ b/include/ClientGenerator.h @@ -64,6 +64,48 @@ class [[nodiscard("unnecessary construction")]] Generator const std::string& outerScope, const ResponseField& responseField) const noexcept; [[nodiscard("unnecessary memory copy")]] static std::string getTypeModifierList( const TypeModifierStack& modifiers) noexcept; + void outputResponseFieldVisitorStates(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parent = {}) const noexcept; + void outputResponseFieldVisitorAddValue(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState = {}, + std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept; + void outputResponseFieldVisitorReserve(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState = {}, + std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept; + void outputResponseFieldVisitorStartObject(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState = {}, + std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept; + void outputResponseFieldVisitorAddMember(std::ostream& sourceFile, + const ResponseFieldList& children, std::string_view parentState = {}) const noexcept; + void outputResponseFieldVisitorEndObject(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState = {}) const noexcept; + void outputResponseFieldVisitorStartArray(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState = {}, + std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept; + void outputResponseFieldVisitorEndArray(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState = {}) const noexcept; + void outputResponseFieldVisitorAddNull(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState = {}, + std::string_view parentAccessor = {}) const noexcept; + void outputResponseFieldVisitorAddMovedValue(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view movedCppType, + std::string_view parentState = {}, std::string_view parentAccessor = {}) const noexcept; + void outputResponseFieldVisitorAddString( + std::ostream& sourceFile, const ResponseField& responseField) const noexcept; + void outputResponseFieldVisitorAddEnum(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState = {}, + std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept; + void outputResponseFieldVisitorAddId( + std::ostream& sourceFile, const ResponseField& responseField) const noexcept; + void outputResponseFieldVisitorAddCopiedValue(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view copiedCppType, + std::string_view parentState = {}, std::string_view parentAccessor = {}) const noexcept; + void outputResponseFieldVisitorAddBool( + std::ostream& sourceFile, const ResponseField& responseField) const noexcept; + void outputResponseFieldVisitorAddInt( + std::ostream& sourceFile, const ResponseField& responseField) const noexcept; + void outputResponseFieldVisitorAddFloat( + std::ostream& sourceFile, const ResponseField& responseField) const noexcept; const SchemaLoader _schemaLoader; const RequestLoader _requestLoader; diff --git a/samples/client/benchmark.cpp b/samples/client/benchmark.cpp index 66723db2..41951aa3 100644 --- a/samples/client/benchmark.cpp +++ b/samples/client/benchmark.cpp @@ -86,7 +86,6 @@ int main(int argc, char** argv) const auto mockService = today::mock_service(); const auto& service = mockService->service; std::vector durationResolve(iterations); - std::vector durationParseServiceResponse(iterations); std::vector durationParseResponse(iterations); const auto startTime = std::chrono::steady_clock::now(); @@ -96,19 +95,21 @@ int main(int argc, char** argv) auto query = GetRequestObject(); const auto& name = GetOperationName(); + auto visitor = std::make_shared(); + auto responseVisitor = std::make_shared(visitor); for (std::size_t i = 0; i < iterations; ++i) { const auto startResolve = std::chrono::steady_clock::now(); - auto response = service->resolve({ query, name }).get(); - const auto startParseServiceResponse = std::chrono::steady_clock::now(); - auto serviceResponse = client::parseServiceResponse(std::move(response)); + auto response = service->visit({ query, name }).get(); const auto startParseResponse = std::chrono::steady_clock::now(); - const auto parsed = parseResponse(std::move(serviceResponse.data)); + + std::move(response.data).visit(responseVisitor); + + const auto parsed = visitor->response(); const auto endParseResponse = std::chrono::steady_clock::now(); - durationResolve[i] = startParseServiceResponse - startResolve; - durationParseServiceResponse[i] = startParseResponse - startParseServiceResponse; + durationResolve[i] = startParseResponse - startResolve; durationParseResponse[i] = endParseResponse - startParseResponse; } } @@ -124,7 +125,6 @@ int main(int argc, char** argv) outputOverview(iterations, totalDuration); outputSegment("Resolve"sv, durationResolve); - outputSegment("ParseServiceResponse"sv, durationParseServiceResponse); outputSegment("ParseResponse"sv, durationParseResponse); return 0; diff --git a/samples/client/benchmark/TodayClient.cpp b/samples/client/benchmark/TodayClient.cpp index 0f65eae7..e8e67d9f 100644 --- a/samples/client/benchmark/TodayClient.cpp +++ b/samples/client/benchmark/TodayClient.cpp @@ -185,6 +185,353 @@ const std::string& GetOperationName() noexcept return s_name; } +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_appointments, + Member_appointments_pageInfo, + Member_appointments_pageInfo_hasNextPage, + Member_appointments_edges, + Member_appointments_edges_0, + Member_appointments_edges_0_node, + Member_appointments_edges_0_node_id, + Member_appointments_edges_0_node_when, + Member_appointments_edges_0_node_subject, + Member_appointments_edges_0_node_isNow, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.appointments = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_pageInfo: + _pimpl->state = impl::VisitorState::Member_appointments; + _pimpl->response.appointments.pageInfo = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_pageInfo_hasNextPage: + _pimpl->state = impl::VisitorState::Member_appointments_pageInfo; + _pimpl->response.appointments.pageInfo.hasNextPage = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->push_back(ModifiedResponse::parse(response::Value { *value })); + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->response.appointments.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->id = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_when: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->when = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_subject: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->subject = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_isNow: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->isNow = ModifiedResponse::parse(response::Value { *value }); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->reserve(count); + break; + + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->push_back(std::make_optional({})); + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->response.appointments.edges->back()->node = std::make_optional({}); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "appointments"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments; + } + break; + + case impl::VisitorState::Member_appointments: + if (key == "pageInfo"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_pageInfo; + } + else if (key == "edges"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges; + } + break; + + case impl::VisitorState::Member_appointments_pageInfo: + if (key == "hasNextPage"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_pageInfo_hasNextPage; + } + break; + + case impl::VisitorState::Member_appointments_edges_0: + if (key == "node"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + } + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + if (key == "id"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_id; + } + else if (key == "when"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_when; + } + else if (key == "subject"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_subject; + } + else if (key == "isNow"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_isNow; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_pageInfo: + _pimpl->state = impl::VisitorState::Member_appointments; + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + break; + + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->response.appointments.edges = std::make_optional>>({}); + break; + + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->state = impl::VisitorState::Member_appointments; + break; + + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->push_back(std::nullopt); + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->response.appointments.edges->back()->node = std::nullopt; + break; + + case impl::VisitorState::Member_appointments_edges_0_node_when: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->when = std::nullopt; + break; + + case impl::VisitorState::Member_appointments_edges_0_node_subject: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->subject = std::nullopt; + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0_node_subject: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->subject = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->id = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_pageInfo_hasNextPage: + _pimpl->state = impl::VisitorState::Member_appointments_pageInfo; + _pimpl->response.appointments.pageInfo.hasNextPage = value; + break; + + case impl::VisitorState::Member_appointments_edges_0_node_isNow: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->isNow = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::client; diff --git a/samples/client/benchmark/TodayClient.h b/samples/client/benchmark/TodayClient.h index 453685fe..6acd89b6 100644 --- a/samples/client/benchmark/TodayClient.h +++ b/samples/client/benchmark/TodayClient.h @@ -92,6 +92,37 @@ struct [[nodiscard("unnecessary construction")]] Response appointments_AppointmentConnection appointments {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -101,6 +132,7 @@ struct Traits [[nodiscard("unnecessary call")]] static const std::string& GetOperationName() noexcept; using Response = Query::Response; + using ResponseVisitor = Query::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; diff --git a/samples/client/benchmark/TodayClient.ixx b/samples/client/benchmark/TodayClient.ixx index 5631ad46..6ddf5cdc 100644 --- a/samples/client/benchmark/TodayClient.ixx +++ b/samples/client/benchmark/TodayClient.ixx @@ -23,6 +23,7 @@ using graphql::today::client::GetRequestObject; using Query::GetOperationName; using Query::Response; +using Query::ResponseVisitor; using Query::parseResponse; using Query::Traits; diff --git a/samples/client/multiple/MultipleQueriesClient.cpp b/samples/client/multiple/MultipleQueriesClient.cpp index 92959f11..da1d8b40 100644 --- a/samples/client/multiple/MultipleQueriesClient.cpp +++ b/samples/client/multiple/MultipleQueriesClient.cpp @@ -285,6 +285,336 @@ const std::string& GetOperationName() noexcept return s_name; } +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_appointments, + Member_appointments_edges, + Member_appointments_edges_0, + Member_appointments_edges_0_node, + Member_appointments_edges_0_node_id, + Member_appointments_edges_0_node_subject, + Member_appointments_edges_0_node_when, + Member_appointments_edges_0_node_isNow, + Member_appointments_edges_0_node__typename, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.appointments = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->push_back(ModifiedResponse::parse(response::Value { *value })); + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->response.appointments.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->id = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_subject: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->subject = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_when: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->when = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_isNow: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->isNow = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->_typename = ModifiedResponse::parse(response::Value { *value }); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->reserve(count); + break; + + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->push_back(std::make_optional({})); + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->response.appointments.edges->back()->node = std::make_optional({}); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "appointments"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments; + } + break; + + case impl::VisitorState::Member_appointments: + if (key == "edges"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges; + } + break; + + case impl::VisitorState::Member_appointments_edges_0: + if (key == "node"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + } + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + if (key == "id"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_id; + } + else if (key == "subject"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_subject; + } + else if (key == "when"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_when; + } + else if (key == "isNow"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_isNow; + } + else if (key == "__typename"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node__typename; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + break; + + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->response.appointments.edges = std::make_optional>>({}); + break; + + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->state = impl::VisitorState::Member_appointments; + break; + + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->push_back(std::nullopt); + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->response.appointments.edges->back()->node = std::nullopt; + break; + + case impl::VisitorState::Member_appointments_edges_0_node_subject: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->subject = std::nullopt; + break; + + case impl::VisitorState::Member_appointments_edges_0_node_when: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->when = std::nullopt; + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0_node_subject: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->subject = std::move(value); + break; + + case impl::VisitorState::Member_appointments_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->_typename = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->id = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0_node_isNow: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->isNow = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::client; @@ -425,6 +755,321 @@ const std::string& GetOperationName() noexcept return s_name; } +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_tasks, + Member_tasks_edges, + Member_tasks_edges_0, + Member_tasks_edges_0_node, + Member_tasks_edges_0_node_id, + Member_tasks_edges_0_node_title, + Member_tasks_edges_0_node_isComplete, + Member_tasks_edges_0_node__typename, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_tasks: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.tasks = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks_edges_0: + _pimpl->response.tasks.edges->push_back(ModifiedResponse::parse(response::Value { *value })); + break; + + case impl::VisitorState::Member_tasks_edges_0_node: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0; + _pimpl->response.tasks.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->id = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks_edges_0_node_title: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->title = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks_edges_0_node_isComplete: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->isComplete = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->_typename = ModifiedResponse::parse(response::Value { *value }); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_tasks_edges_0: + _pimpl->response.tasks.edges->reserve(count); + break; + + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_tasks_edges_0: + _pimpl->response.tasks.edges->push_back(std::make_optional({})); + break; + + case impl::VisitorState::Member_tasks_edges_0_node: + _pimpl->response.tasks.edges->back()->node = std::make_optional({}); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "tasks"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks; + } + break; + + case impl::VisitorState::Member_tasks: + if (key == "edges"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges; + } + break; + + case impl::VisitorState::Member_tasks_edges_0: + if (key == "node"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + } + break; + + case impl::VisitorState::Member_tasks_edges_0_node: + if (key == "id"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node_id; + } + else if (key == "title"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node_title; + } + else if (key == "isComplete"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node_isComplete; + } + else if (key == "__typename"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node__typename; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_tasks_edges_0_node: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0; + break; + + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_tasks_edges: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0; + _pimpl->response.tasks.edges = std::make_optional>>({}); + break; + + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_tasks_edges_0: + _pimpl->state = impl::VisitorState::Member_tasks; + break; + + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_tasks_edges_0: + _pimpl->response.tasks.edges->push_back(std::nullopt); + break; + + case impl::VisitorState::Member_tasks_edges_0_node: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0; + _pimpl->response.tasks.edges->back()->node = std::nullopt; + break; + + case impl::VisitorState::Member_tasks_edges_0_node_title: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->title = std::nullopt; + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_tasks_edges_0_node_title: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->title = std::move(value); + break; + + case impl::VisitorState::Member_tasks_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->_typename = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_tasks_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->id = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_tasks_edges_0_node_isComplete: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->isComplete = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::client; @@ -551,18 +1196,333 @@ graphql::multiple::client::query::UnreadCounts::Response::unreadCounts_FolderCon } } - return result; + return result; +} + +} // namespace client + +namespace multiple::client::query::UnreadCounts { + +const std::string& GetOperationName() noexcept +{ + static const auto s_name = R"gql(UnreadCounts)gql"s; + + return s_name; +} + +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_unreadCounts, + Member_unreadCounts_edges, + Member_unreadCounts_edges_0, + Member_unreadCounts_edges_0_node, + Member_unreadCounts_edges_0_node_id, + Member_unreadCounts_edges_0_node_name, + Member_unreadCounts_edges_0_node_unreadCount, + Member_unreadCounts_edges_0_node__typename, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.unreadCounts = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->response.unreadCounts.edges->push_back(ModifiedResponse::parse(response::Value { *value })); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; + _pimpl->response.unreadCounts.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->id = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node_name: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->name = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node_unreadCount: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->unreadCount = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->_typename = ModifiedResponse::parse(response::Value { *value }); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->response.unreadCounts.edges->reserve(count); + break; + + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->response.unreadCounts.edges->push_back(std::make_optional({})); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node: + _pimpl->response.unreadCounts.edges->back()->node = std::make_optional({}); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "unreadCounts"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts; + } + break; + + case impl::VisitorState::Member_unreadCounts: + if (key == "edges"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges; + } + break; + + case impl::VisitorState::Member_unreadCounts_edges_0: + if (key == "node"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + } + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node: + if (key == "id"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node_id; + } + else if (key == "name"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node_name; + } + else if (key == "unreadCount"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node_unreadCount; + } + else if (key == "__typename"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node__typename; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts_edges_0_node: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; + break; + + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts_edges: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; + _pimpl->response.unreadCounts.edges = std::make_optional>>({}); + break; + + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->state = impl::VisitorState::Member_unreadCounts; + break; + + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->response.unreadCounts.edges->push_back(std::nullopt); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; + _pimpl->response.unreadCounts.edges->back()->node = std::nullopt; + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node_name: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->name = std::nullopt; + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts_edges_0_node_name: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->name = std::move(value); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->_typename = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->id = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts_edges_0_node_unreadCount: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->unreadCount = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; } -} // namespace client +Response ResponseVisitor::response() +{ + Response response {}; -namespace multiple::client::query::UnreadCounts { + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; -const std::string& GetOperationName() noexcept -{ - static const auto s_name = R"gql(UnreadCounts)gql"s; + default: + break; + } - return s_name; + return response; } Response parseResponse(response::Value&& response) @@ -614,6 +1574,13 @@ namespace client { using namespace multiple; +static const std::array, 4> s_valuesTaskState = { + std::make_pair(R"gql(New)gql"sv, TaskState::New), + std::make_pair(R"gql(Started)gql"sv, TaskState::Started), + std::make_pair(R"gql(Complete)gql"sv, TaskState::Complete), + std::make_pair(R"gql(Unassigned)gql"sv, TaskState::Unassigned) +}; + template <> TaskState Response::parse(response::Value&& value) { @@ -622,15 +1589,8 @@ TaskState Response::parse(response::Value&& value) throw std::logic_error { R"ex(not a valid TaskState value)ex" }; } - static const std::array, 4> s_values = { - std::make_pair(R"gql(New)gql"sv, TaskState::New), - std::make_pair(R"gql(Started)gql"sv, TaskState::Started), - std::make_pair(R"gql(Complete)gql"sv, TaskState::Complete), - std::make_pair(R"gql(Unassigned)gql"sv, TaskState::Unassigned) - }; - const auto result = internal::sorted_map_lookup( - s_values, + s_valuesTaskState, std::string_view { value.get() }); if (!result) @@ -704,6 +1664,369 @@ const std::string& GetOperationName() noexcept return s_name; } +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_testTaskState, + Member_anyType, + Member_anyType_0, + Member_anyType_0__typename, + Member_anyType_0_id, + Member_anyType_0_title, + Member_anyType_0_isComplete, + Member_anyType_0_subject, + Member_anyType_0_when, + Member_anyType_0_isNow, + Member_default_, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_testTaskState: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.testTaskState = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0: + _pimpl->response.anyType.push_back(ModifiedResponse::parse(response::Value { *value })); + break; + + case impl::VisitorState::Member_anyType_0__typename: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->_typename = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_id: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->id = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_title: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->title = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_isComplete: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->isComplete = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_subject: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->subject = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_when: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->when = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_isNow: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->isNow = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_default_: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.default_ = ModifiedResponse::parse(response::Value { *value }); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_anyType_0: + _pimpl->response.anyType.reserve(count); + break; + + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_anyType_0: + _pimpl->response.anyType.push_back(std::make_optional({})); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "testTaskState"sv) + { + _pimpl->state = impl::VisitorState::Member_testTaskState; + } + else if (key == "anyType"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType; + } + else if (key == "default"sv) + { + _pimpl->state = impl::VisitorState::Member_default_; + } + break; + + case impl::VisitorState::Member_anyType_0: + if (key == "__typename"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0__typename; + } + else if (key == "id"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_id; + } + else if (key == "title"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_title; + } + else if (key == "isComplete"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_isComplete; + } + else if (key == "subject"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_subject; + } + else if (key == "when"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_when; + } + else if (key == "isNow"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_isNow; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_anyType: + _pimpl->state = impl::VisitorState::Member_anyType_0; + break; + + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_anyType_0: + _pimpl->state = impl::VisitorState::Start; + break; + + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_anyType_0: + _pimpl->response.anyType.push_back(std::nullopt); + break; + + case impl::VisitorState::Member_anyType_0_title: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->title = std::nullopt; + break; + + case impl::VisitorState::Member_anyType_0_subject: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->subject = std::nullopt; + break; + + case impl::VisitorState::Member_anyType_0_when: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->when = std::nullopt; + break; + + case impl::VisitorState::Member_default_: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.default_ = std::nullopt; + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_anyType_0__typename: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->_typename = std::move(value); + break; + + case impl::VisitorState::Member_anyType_0_title: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->title = std::move(value); + break; + + case impl::VisitorState::Member_anyType_0_subject: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->subject = std::move(value); + break; + + case impl::VisitorState::Member_default_: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.default_ = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_testTaskState: + _pimpl->state = impl::VisitorState::Start; + if (const auto enumValue = internal::sorted_map_lookup(s_valuesTaskState, std::string_view { value })) + { + _pimpl->response.testTaskState = *enumValue; + } + break; + + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_anyType_0_id: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->id = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_anyType_0_isComplete: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->isComplete = value; + break; + + case impl::VisitorState::Member_anyType_0_isNow: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->isNow = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::client; @@ -875,6 +2198,292 @@ response::Value serializeVariables(Variables&& variables) return result; } +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_completedTask, + Member_completedTask_completedTask, + Member_completedTask_completedTask_completedTaskId, + Member_completedTask_completedTask_title, + Member_completedTask_completedTask_isComplete, + Member_completedTask_clientMutationId, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.completedTask = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_completedTask_completedTask: + _pimpl->state = impl::VisitorState::Member_completedTask; + _pimpl->response.completedTask.completedTask = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_completedTask_completedTask_completedTaskId: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->completedTaskId = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_completedTask_completedTask_title: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->title = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_completedTask_completedTask_isComplete: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->isComplete = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_completedTask_clientMutationId: + _pimpl->state = impl::VisitorState::Member_completedTask; + _pimpl->response.completedTask.clientMutationId = ModifiedResponse::parse(response::Value { *value }); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask: + _pimpl->response.completedTask.completedTask = std::make_optional({}); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "completedTask"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask; + } + break; + + case impl::VisitorState::Member_completedTask: + if (key == "completedTask"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + } + else if (key == "clientMutationId"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask_clientMutationId; + } + break; + + case impl::VisitorState::Member_completedTask_completedTask: + if (key == "completedTaskId"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask_completedTaskId; + } + else if (key == "title"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask_title; + } + else if (key == "isComplete"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask_isComplete; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask: + _pimpl->state = impl::VisitorState::Member_completedTask; + break; + + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask: + _pimpl->state = impl::VisitorState::Member_completedTask; + _pimpl->response.completedTask.completedTask = std::nullopt; + break; + + case impl::VisitorState::Member_completedTask_completedTask_title: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->title = std::nullopt; + break; + + case impl::VisitorState::Member_completedTask_clientMutationId: + _pimpl->state = impl::VisitorState::Member_completedTask; + _pimpl->response.completedTask.clientMutationId = std::nullopt; + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask_title: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->title = std::move(value); + break; + + case impl::VisitorState::Member_completedTask_clientMutationId: + _pimpl->state = impl::VisitorState::Member_completedTask; + _pimpl->response.completedTask.clientMutationId = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask_completedTaskId: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->completedTaskId = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask_isComplete: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->isComplete = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::client; diff --git a/samples/client/multiple/MultipleQueriesClient.h b/samples/client/multiple/MultipleQueriesClient.h index 8806bec7..4e711034 100644 --- a/samples/client/multiple/MultipleQueriesClient.h +++ b/samples/client/multiple/MultipleQueriesClient.h @@ -180,6 +180,37 @@ struct [[nodiscard("unnecessary construction")]] Response appointments_AppointmentConnection appointments {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -189,6 +220,7 @@ struct Traits [[nodiscard("unnecessary call")]] static const std::string& GetOperationName() noexcept; using Response = Appointments::Response; + using ResponseVisitor = Appointments::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; @@ -226,6 +258,37 @@ struct [[nodiscard("unnecessary construction")]] Response tasks_TaskConnection tasks {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -235,6 +298,7 @@ struct Traits [[nodiscard("unnecessary call")]] static const std::string& GetOperationName() noexcept; using Response = Tasks::Response; + using ResponseVisitor = Tasks::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; @@ -272,6 +336,37 @@ struct [[nodiscard("unnecessary construction")]] Response unreadCounts_FolderConnection unreadCounts {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -281,6 +376,7 @@ struct Traits [[nodiscard("unnecessary call")]] static const std::string& GetOperationName() noexcept; using Response = UnreadCounts::Response; + using ResponseVisitor = UnreadCounts::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; @@ -315,6 +411,37 @@ struct [[nodiscard("unnecessary construction")]] Response std::optional default_ {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -324,6 +451,7 @@ struct Traits [[nodiscard("unnecessary call")]] static const std::string& GetOperationName() noexcept; using Response = Miscellaneous::Response; + using ResponseVisitor = Miscellaneous::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; @@ -368,6 +496,37 @@ struct [[nodiscard("unnecessary construction")]] Response completedTask_CompleteTaskPayload completedTask {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -381,6 +540,7 @@ struct Traits [[nodiscard("unnecessary conversion")]] static response::Value serializeVariables(Variables&& variables); using Response = CompleteTaskMutation::Response; + using ResponseVisitor = CompleteTaskMutation::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; diff --git a/samples/client/multiple/MultipleQueriesClient.ixx b/samples/client/multiple/MultipleQueriesClient.ixx index d21f7130..22f60abd 100644 --- a/samples/client/multiple/MultipleQueriesClient.ixx +++ b/samples/client/multiple/MultipleQueriesClient.ixx @@ -31,6 +31,7 @@ using graphql::multiple::client::GetRequestObject; using Appointments::GetOperationName; using Appointments::Response; +using Appointments::ResponseVisitor; using Appointments::parseResponse; using Appointments::Traits; @@ -44,6 +45,7 @@ using graphql::multiple::client::GetRequestObject; using Tasks::GetOperationName; using Tasks::Response; +using Tasks::ResponseVisitor; using Tasks::parseResponse; using Tasks::Traits; @@ -57,6 +59,7 @@ using graphql::multiple::client::GetRequestObject; using UnreadCounts::GetOperationName; using UnreadCounts::Response; +using UnreadCounts::ResponseVisitor; using UnreadCounts::parseResponse; using UnreadCounts::Traits; @@ -72,6 +75,7 @@ using Miscellaneous::GetOperationName; using graphql::multiple::TaskState; using Miscellaneous::Response; +using Miscellaneous::ResponseVisitor; using Miscellaneous::parseResponse; using Miscellaneous::Traits; @@ -92,6 +96,7 @@ using CompleteTaskMutation::Variables; using CompleteTaskMutation::serializeVariables; using CompleteTaskMutation::Response; +using CompleteTaskMutation::ResponseVisitor; using CompleteTaskMutation::parseResponse; using CompleteTaskMutation::Traits; diff --git a/samples/client/mutate/MutateClient.cpp b/samples/client/mutate/MutateClient.cpp index a0f26f85..7d8840bf 100644 --- a/samples/client/mutate/MutateClient.cpp +++ b/samples/client/mutate/MutateClient.cpp @@ -152,6 +152,13 @@ response::Value Variable::serialize(CompleteTaskInput&& input return result; } +static const std::array, 4> s_valuesTaskState = { + std::make_pair(R"gql(New)gql"sv, TaskState::New), + std::make_pair(R"gql(Started)gql"sv, TaskState::Started), + std::make_pair(R"gql(Complete)gql"sv, TaskState::Complete), + std::make_pair(R"gql(Unassigned)gql"sv, TaskState::Unassigned) +}; + template <> TaskState Response::parse(response::Value&& value) { @@ -160,15 +167,8 @@ TaskState Response::parse(response::Value&& value) throw std::logic_error { R"ex(not a valid TaskState value)ex" }; } - static const std::array, 4> s_values = { - std::make_pair(R"gql(New)gql"sv, TaskState::New), - std::make_pair(R"gql(Started)gql"sv, TaskState::Started), - std::make_pair(R"gql(Complete)gql"sv, TaskState::Complete), - std::make_pair(R"gql(Unassigned)gql"sv, TaskState::Unassigned) - }; - const auto result = internal::sorted_map_lookup( - s_values, + s_valuesTaskState, std::string_view { value.get() }); if (!result) @@ -261,6 +261,292 @@ response::Value serializeVariables(Variables&& variables) return result; } +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_completedTask, + Member_completedTask_completedTask, + Member_completedTask_completedTask_completedTaskId, + Member_completedTask_completedTask_title, + Member_completedTask_completedTask_isComplete, + Member_completedTask_clientMutationId, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.completedTask = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_completedTask_completedTask: + _pimpl->state = impl::VisitorState::Member_completedTask; + _pimpl->response.completedTask.completedTask = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_completedTask_completedTask_completedTaskId: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->completedTaskId = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_completedTask_completedTask_title: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->title = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_completedTask_completedTask_isComplete: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->isComplete = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_completedTask_clientMutationId: + _pimpl->state = impl::VisitorState::Member_completedTask; + _pimpl->response.completedTask.clientMutationId = ModifiedResponse::parse(response::Value { *value }); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask: + _pimpl->response.completedTask.completedTask = std::make_optional({}); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "completedTask"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask; + } + break; + + case impl::VisitorState::Member_completedTask: + if (key == "completedTask"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + } + else if (key == "clientMutationId"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask_clientMutationId; + } + break; + + case impl::VisitorState::Member_completedTask_completedTask: + if (key == "completedTaskId"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask_completedTaskId; + } + else if (key == "title"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask_title; + } + else if (key == "isComplete"sv) + { + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask_isComplete; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask: + _pimpl->state = impl::VisitorState::Member_completedTask; + break; + + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask: + _pimpl->state = impl::VisitorState::Member_completedTask; + _pimpl->response.completedTask.completedTask = std::nullopt; + break; + + case impl::VisitorState::Member_completedTask_completedTask_title: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->title = std::nullopt; + break; + + case impl::VisitorState::Member_completedTask_clientMutationId: + _pimpl->state = impl::VisitorState::Member_completedTask; + _pimpl->response.completedTask.clientMutationId = std::nullopt; + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask_title: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->title = std::move(value); + break; + + case impl::VisitorState::Member_completedTask_clientMutationId: + _pimpl->state = impl::VisitorState::Member_completedTask; + _pimpl->response.completedTask.clientMutationId = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask_completedTaskId: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->completedTaskId = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_completedTask_completedTask_isComplete: + _pimpl->state = impl::VisitorState::Member_completedTask_completedTask; + _pimpl->response.completedTask.completedTask->isComplete = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::client; diff --git a/samples/client/mutate/MutateClient.h b/samples/client/mutate/MutateClient.h index ab016aaa..4c945b24 100644 --- a/samples/client/mutate/MutateClient.h +++ b/samples/client/mutate/MutateClient.h @@ -119,6 +119,37 @@ struct [[nodiscard("unnecessary construction")]] Response completedTask_CompleteTaskPayload completedTask {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -132,6 +163,7 @@ struct Traits [[nodiscard("unnecessary conversion")]] static response::Value serializeVariables(Variables&& variables); using Response = CompleteTaskMutation::Response; + using ResponseVisitor = CompleteTaskMutation::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; diff --git a/samples/client/mutate/MutateClient.ixx b/samples/client/mutate/MutateClient.ixx index 4e781529..6015a4cb 100644 --- a/samples/client/mutate/MutateClient.ixx +++ b/samples/client/mutate/MutateClient.ixx @@ -38,6 +38,7 @@ using CompleteTaskMutation::Variables; using CompleteTaskMutation::serializeVariables; using CompleteTaskMutation::Response; +using CompleteTaskMutation::ResponseVisitor; using CompleteTaskMutation::parseResponse; using CompleteTaskMutation::Traits; diff --git a/samples/client/nestedinput/NestedInputClient.cpp b/samples/client/nestedinput/NestedInputClient.cpp index a70c79ba..9e8d3f90 100644 --- a/samples/client/nestedinput/NestedInputClient.cpp +++ b/samples/client/nestedinput/NestedInputClient.cpp @@ -356,6 +356,242 @@ response::Value serializeVariables(Variables&& variables) return result; } +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_control, + Member_control_test, + Member_control_test_id, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_control: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.control = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_control_test: + _pimpl->state = impl::VisitorState::Member_control; + _pimpl->response.control.test = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_control_test_id: + _pimpl->state = impl::VisitorState::Member_control_test; + _pimpl->response.control.test->id = ModifiedResponse::parse(response::Value { *value }); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_control_test: + _pimpl->response.control.test = std::make_optional({}); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "control"sv) + { + _pimpl->state = impl::VisitorState::Member_control; + } + break; + + case impl::VisitorState::Member_control: + if (key == "test"sv) + { + _pimpl->state = impl::VisitorState::Member_control_test; + } + break; + + case impl::VisitorState::Member_control_test: + if (key == "id"sv) + { + _pimpl->state = impl::VisitorState::Member_control_test_id; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_control_test: + _pimpl->state = impl::VisitorState::Member_control; + break; + + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_control_test: + _pimpl->state = impl::VisitorState::Member_control; + _pimpl->response.control.test = std::nullopt; + break; + + case impl::VisitorState::Member_control_test_id: + _pimpl->state = impl::VisitorState::Member_control_test; + _pimpl->response.control.test->id = std::nullopt; + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_control_test_id: + _pimpl->state = impl::VisitorState::Member_control_test; + _pimpl->response.control.test->id = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::client; diff --git a/samples/client/nestedinput/NestedInputClient.h b/samples/client/nestedinput/NestedInputClient.h index 2350eb51..06fc137d 100644 --- a/samples/client/nestedinput/NestedInputClient.h +++ b/samples/client/nestedinput/NestedInputClient.h @@ -153,6 +153,37 @@ struct [[nodiscard("unnecessary construction")]] Response control_Control control {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -166,6 +197,7 @@ struct Traits [[nodiscard("unnecessary conversion")]] static response::Value serializeVariables(Variables&& variables); using Response = testQuery::Response; + using ResponseVisitor = testQuery::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; diff --git a/samples/client/nestedinput/NestedInputClient.ixx b/samples/client/nestedinput/NestedInputClient.ixx index 71430abe..44459e49 100644 --- a/samples/client/nestedinput/NestedInputClient.ixx +++ b/samples/client/nestedinput/NestedInputClient.ixx @@ -40,6 +40,7 @@ using testQuery::Variables; using testQuery::serializeVariables; using testQuery::Response; +using testQuery::ResponseVisitor; using testQuery::parseResponse; using testQuery::Traits; diff --git a/samples/client/query/QueryClient.cpp b/samples/client/query/QueryClient.cpp index 46f381f0..50e333d9 100644 --- a/samples/client/query/QueryClient.cpp +++ b/samples/client/query/QueryClient.cpp @@ -110,6 +110,13 @@ namespace client { using namespace query; +static const std::array, 4> s_valuesTaskState = { + std::make_pair(R"gql(New)gql"sv, TaskState::New), + std::make_pair(R"gql(Started)gql"sv, TaskState::Started), + std::make_pair(R"gql(Complete)gql"sv, TaskState::Complete), + std::make_pair(R"gql(Unassigned)gql"sv, TaskState::Unassigned) +}; + template <> TaskState Response::parse(response::Value&& value) { @@ -118,15 +125,8 @@ TaskState Response::parse(response::Value&& value) throw std::logic_error { R"ex(not a valid TaskState value)ex" }; } - static const std::array, 4> s_values = { - std::make_pair(R"gql(New)gql"sv, TaskState::New), - std::make_pair(R"gql(Started)gql"sv, TaskState::Started), - std::make_pair(R"gql(Complete)gql"sv, TaskState::Complete), - std::make_pair(R"gql(Unassigned)gql"sv, TaskState::Unassigned) - }; - const auto result = internal::sorted_map_lookup( - s_values, + s_valuesTaskState, std::string_view { value.get() }); if (!result) @@ -448,6 +448,798 @@ const std::string& GetOperationName() noexcept return s_name; } +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_appointments, + Member_appointments_edges, + Member_appointments_edges_0, + Member_appointments_edges_0_node, + Member_appointments_edges_0_node_id, + Member_appointments_edges_0_node_subject, + Member_appointments_edges_0_node_when, + Member_appointments_edges_0_node_isNow, + Member_appointments_edges_0_node__typename, + Member_tasks, + Member_tasks_edges, + Member_tasks_edges_0, + Member_tasks_edges_0_node, + Member_tasks_edges_0_node_id, + Member_tasks_edges_0_node_title, + Member_tasks_edges_0_node_isComplete, + Member_tasks_edges_0_node__typename, + Member_unreadCounts, + Member_unreadCounts_edges, + Member_unreadCounts_edges_0, + Member_unreadCounts_edges_0_node, + Member_unreadCounts_edges_0_node_id, + Member_unreadCounts_edges_0_node_name, + Member_unreadCounts_edges_0_node_unreadCount, + Member_unreadCounts_edges_0_node__typename, + Member_testTaskState, + Member_anyType, + Member_anyType_0, + Member_anyType_0__typename, + Member_anyType_0_id, + Member_anyType_0_title, + Member_anyType_0_isComplete, + Member_anyType_0_subject, + Member_anyType_0_when, + Member_anyType_0_isNow, + Member_default_, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.appointments = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->push_back(ModifiedResponse::parse(response::Value { *value })); + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->response.appointments.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->id = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_subject: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->subject = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_when: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->when = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node_isNow: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->isNow = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_appointments_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->_typename = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.tasks = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks_edges_0: + _pimpl->response.tasks.edges->push_back(ModifiedResponse::parse(response::Value { *value })); + break; + + case impl::VisitorState::Member_tasks_edges_0_node: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0; + _pimpl->response.tasks.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->id = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks_edges_0_node_title: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->title = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks_edges_0_node_isComplete: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->isComplete = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_tasks_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->_typename = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.unreadCounts = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->response.unreadCounts.edges->push_back(ModifiedResponse::parse(response::Value { *value })); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; + _pimpl->response.unreadCounts.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->id = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node_name: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->name = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node_unreadCount: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->unreadCount = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->_typename = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_testTaskState: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.testTaskState = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0: + _pimpl->response.anyType.push_back(ModifiedResponse::parse(response::Value { *value })); + break; + + case impl::VisitorState::Member_anyType_0__typename: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->_typename = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_id: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->id = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_title: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->title = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_isComplete: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->isComplete = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_subject: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->subject = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_when: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->when = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_anyType_0_isNow: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->isNow = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_default_: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.default_ = ModifiedResponse::parse(response::Value { *value }); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->reserve(count); + break; + + case impl::VisitorState::Member_tasks_edges_0: + _pimpl->response.tasks.edges->reserve(count); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->response.unreadCounts.edges->reserve(count); + break; + + case impl::VisitorState::Member_anyType_0: + _pimpl->response.anyType.reserve(count); + break; + + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->push_back(std::make_optional({})); + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->response.appointments.edges->back()->node = std::make_optional({}); + break; + + case impl::VisitorState::Member_tasks_edges_0: + _pimpl->response.tasks.edges->push_back(std::make_optional({})); + break; + + case impl::VisitorState::Member_tasks_edges_0_node: + _pimpl->response.tasks.edges->back()->node = std::make_optional({}); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->response.unreadCounts.edges->push_back(std::make_optional({})); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node: + _pimpl->response.unreadCounts.edges->back()->node = std::make_optional({}); + break; + + case impl::VisitorState::Member_anyType_0: + _pimpl->response.anyType.push_back(std::make_optional({})); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "appointments"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments; + } + else if (key == "tasks"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks; + } + else if (key == "unreadCounts"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts; + } + else if (key == "testTaskState"sv) + { + _pimpl->state = impl::VisitorState::Member_testTaskState; + } + else if (key == "anyType"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType; + } + else if (key == "default"sv) + { + _pimpl->state = impl::VisitorState::Member_default_; + } + break; + + case impl::VisitorState::Member_appointments: + if (key == "edges"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges; + } + break; + + case impl::VisitorState::Member_appointments_edges_0: + if (key == "node"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + } + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + if (key == "id"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_id; + } + else if (key == "subject"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_subject; + } + else if (key == "when"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_when; + } + else if (key == "isNow"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node_isNow; + } + else if (key == "__typename"sv) + { + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node__typename; + } + break; + + case impl::VisitorState::Member_tasks: + if (key == "edges"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges; + } + break; + + case impl::VisitorState::Member_tasks_edges_0: + if (key == "node"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + } + break; + + case impl::VisitorState::Member_tasks_edges_0_node: + if (key == "id"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node_id; + } + else if (key == "title"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node_title; + } + else if (key == "isComplete"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node_isComplete; + } + else if (key == "__typename"sv) + { + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node__typename; + } + break; + + case impl::VisitorState::Member_unreadCounts: + if (key == "edges"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges; + } + break; + + case impl::VisitorState::Member_unreadCounts_edges_0: + if (key == "node"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + } + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node: + if (key == "id"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node_id; + } + else if (key == "name"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node_name; + } + else if (key == "unreadCount"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node_unreadCount; + } + else if (key == "__typename"sv) + { + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node__typename; + } + break; + + case impl::VisitorState::Member_anyType_0: + if (key == "__typename"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0__typename; + } + else if (key == "id"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_id; + } + else if (key == "title"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_title; + } + else if (key == "isComplete"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_isComplete; + } + else if (key == "subject"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_subject; + } + else if (key == "when"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_when; + } + else if (key == "isNow"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_isNow; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + break; + + case impl::VisitorState::Member_tasks_edges_0_node: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0; + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; + break; + + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->response.appointments.edges = std::make_optional>>({}); + break; + + case impl::VisitorState::Member_tasks_edges: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0; + _pimpl->response.tasks.edges = std::make_optional>>({}); + break; + + case impl::VisitorState::Member_unreadCounts_edges: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; + _pimpl->response.unreadCounts.edges = std::make_optional>>({}); + break; + + case impl::VisitorState::Member_anyType: + _pimpl->state = impl::VisitorState::Member_anyType_0; + break; + + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->state = impl::VisitorState::Member_appointments; + break; + + case impl::VisitorState::Member_tasks_edges_0: + _pimpl->state = impl::VisitorState::Member_tasks; + break; + + case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->state = impl::VisitorState::Member_unreadCounts; + break; + + case impl::VisitorState::Member_anyType_0: + _pimpl->state = impl::VisitorState::Start; + break; + + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0: + _pimpl->response.appointments.edges->push_back(std::nullopt); + break; + + case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->response.appointments.edges->back()->node = std::nullopt; + break; + + case impl::VisitorState::Member_appointments_edges_0_node_subject: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->subject = std::nullopt; + break; + + case impl::VisitorState::Member_appointments_edges_0_node_when: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->when = std::nullopt; + break; + + case impl::VisitorState::Member_tasks_edges_0: + _pimpl->response.tasks.edges->push_back(std::nullopt); + break; + + case impl::VisitorState::Member_tasks_edges_0_node: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0; + _pimpl->response.tasks.edges->back()->node = std::nullopt; + break; + + case impl::VisitorState::Member_tasks_edges_0_node_title: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->title = std::nullopt; + break; + + case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->response.unreadCounts.edges->push_back(std::nullopt); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; + _pimpl->response.unreadCounts.edges->back()->node = std::nullopt; + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node_name: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->name = std::nullopt; + break; + + case impl::VisitorState::Member_anyType_0: + _pimpl->response.anyType.push_back(std::nullopt); + break; + + case impl::VisitorState::Member_anyType_0_title: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->title = std::nullopt; + break; + + case impl::VisitorState::Member_anyType_0_subject: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->subject = std::nullopt; + break; + + case impl::VisitorState::Member_anyType_0_when: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->when = std::nullopt; + break; + + case impl::VisitorState::Member_default_: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.default_ = std::nullopt; + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0_node_subject: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->subject = std::move(value); + break; + + case impl::VisitorState::Member_appointments_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->_typename = std::move(value); + break; + + case impl::VisitorState::Member_tasks_edges_0_node_title: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->title = std::move(value); + break; + + case impl::VisitorState::Member_tasks_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->_typename = std::move(value); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node_name: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->name = std::move(value); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node__typename: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->_typename = std::move(value); + break; + + case impl::VisitorState::Member_anyType_0__typename: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->_typename = std::move(value); + break; + + case impl::VisitorState::Member_anyType_0_title: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->title = std::move(value); + break; + + case impl::VisitorState::Member_anyType_0_subject: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->subject = std::move(value); + break; + + case impl::VisitorState::Member_default_: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.default_ = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_testTaskState: + _pimpl->state = impl::VisitorState::Start; + if (const auto enumValue = internal::sorted_map_lookup(s_valuesTaskState, std::string_view { value })) + { + _pimpl->response.testTaskState = *enumValue; + } + break; + + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->id = std::move(value); + break; + + case impl::VisitorState::Member_tasks_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->id = std::move(value); + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_node_id: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->id = std::move(value); + break; + + case impl::VisitorState::Member_anyType_0_id: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->id = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_appointments_edges_0_node_isNow: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; + _pimpl->response.appointments.edges->back()->node->isNow = value; + break; + + case impl::VisitorState::Member_tasks_edges_0_node_isComplete: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; + _pimpl->response.tasks.edges->back()->node->isComplete = value; + break; + + case impl::VisitorState::Member_anyType_0_isComplete: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->isComplete = value; + break; + + case impl::VisitorState::Member_anyType_0_isNow: + _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->response.anyType.back()->isNow = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_unreadCounts_edges_0_node_unreadCount: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; + _pimpl->response.unreadCounts.edges->back()->node->unreadCount = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::client; diff --git a/samples/client/query/QueryClient.h b/samples/client/query/QueryClient.h index 57709b13..9f52a969 100644 --- a/samples/client/query/QueryClient.h +++ b/samples/client/query/QueryClient.h @@ -194,6 +194,37 @@ struct [[nodiscard("unnecessary construction")]] Response std::optional default_ {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -203,6 +234,7 @@ struct Traits [[nodiscard("unnecessary call")]] static const std::string& GetOperationName() noexcept; using Response = Query::Response; + using ResponseVisitor = Query::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; diff --git a/samples/client/query/QueryClient.ixx b/samples/client/query/QueryClient.ixx index 7d59ccdf..f069b326 100644 --- a/samples/client/query/QueryClient.ixx +++ b/samples/client/query/QueryClient.ixx @@ -31,6 +31,7 @@ using Query::GetOperationName; using graphql::query::TaskState; using Query::Response; +using Query::ResponseVisitor; using Query::parseResponse; using Query::Traits; diff --git a/samples/client/subscribe/SubscribeClient.cpp b/samples/client/subscribe/SubscribeClient.cpp index 3945722a..daf6e66f 100644 --- a/samples/client/subscribe/SubscribeClient.cpp +++ b/samples/client/subscribe/SubscribeClient.cpp @@ -107,6 +107,270 @@ const std::string& GetOperationName() noexcept return s_name; } +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_nextAppointment, + Member_nextAppointment_nextAppointmentId, + Member_nextAppointment_when, + Member_nextAppointment_subject, + Member_nextAppointment_isNow, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_nextAppointment: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.nextAppointment = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_nextAppointment_nextAppointmentId: + _pimpl->state = impl::VisitorState::Member_nextAppointment; + _pimpl->response.nextAppointment->nextAppointmentId = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_nextAppointment_when: + _pimpl->state = impl::VisitorState::Member_nextAppointment; + _pimpl->response.nextAppointment->when = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_nextAppointment_subject: + _pimpl->state = impl::VisitorState::Member_nextAppointment; + _pimpl->response.nextAppointment->subject = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_nextAppointment_isNow: + _pimpl->state = impl::VisitorState::Member_nextAppointment; + _pimpl->response.nextAppointment->isNow = ModifiedResponse::parse(response::Value { *value }); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_nextAppointment: + _pimpl->response.nextAppointment = std::make_optional({}); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "nextAppointment"sv) + { + _pimpl->state = impl::VisitorState::Member_nextAppointment; + } + break; + + case impl::VisitorState::Member_nextAppointment: + if (key == "nextAppointmentId"sv) + { + _pimpl->state = impl::VisitorState::Member_nextAppointment_nextAppointmentId; + } + else if (key == "when"sv) + { + _pimpl->state = impl::VisitorState::Member_nextAppointment_when; + } + else if (key == "subject"sv) + { + _pimpl->state = impl::VisitorState::Member_nextAppointment_subject; + } + else if (key == "isNow"sv) + { + _pimpl->state = impl::VisitorState::Member_nextAppointment_isNow; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_nextAppointment: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.nextAppointment = std::nullopt; + break; + + case impl::VisitorState::Member_nextAppointment_when: + _pimpl->state = impl::VisitorState::Member_nextAppointment; + _pimpl->response.nextAppointment->when = std::nullopt; + break; + + case impl::VisitorState::Member_nextAppointment_subject: + _pimpl->state = impl::VisitorState::Member_nextAppointment; + _pimpl->response.nextAppointment->subject = std::nullopt; + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_nextAppointment_subject: + _pimpl->state = impl::VisitorState::Member_nextAppointment; + _pimpl->response.nextAppointment->subject = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_nextAppointment_nextAppointmentId: + _pimpl->state = impl::VisitorState::Member_nextAppointment; + _pimpl->response.nextAppointment->nextAppointmentId = std::move(value); + break; + + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_nextAppointment_isNow: + _pimpl->state = impl::VisitorState::Member_nextAppointment; + _pimpl->response.nextAppointment->isNow = value; + break; + + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::client; diff --git a/samples/client/subscribe/SubscribeClient.h b/samples/client/subscribe/SubscribeClient.h index a57fd5cd..de494e84 100644 --- a/samples/client/subscribe/SubscribeClient.h +++ b/samples/client/subscribe/SubscribeClient.h @@ -67,6 +67,37 @@ struct [[nodiscard("unnecessary construction")]] Response std::optional nextAppointment {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -76,6 +107,7 @@ struct Traits [[nodiscard("unnecessary call")]] static const std::string& GetOperationName() noexcept; using Response = TestSubscription::Response; + using ResponseVisitor = TestSubscription::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; diff --git a/samples/client/subscribe/SubscribeClient.ixx b/samples/client/subscribe/SubscribeClient.ixx index 13456256..36dfdbca 100644 --- a/samples/client/subscribe/SubscribeClient.ixx +++ b/samples/client/subscribe/SubscribeClient.ixx @@ -23,6 +23,7 @@ using graphql::subscribe::client::GetRequestObject; using TestSubscription::GetOperationName; using TestSubscription::Response; +using TestSubscription::ResponseVisitor; using TestSubscription::parseResponse; using TestSubscription::Traits; diff --git a/samples/proxy/query/ProxyClient.cpp b/samples/proxy/query/ProxyClient.cpp index d40a39a9..f262a1d8 100644 --- a/samples/proxy/query/ProxyClient.cpp +++ b/samples/proxy/query/ProxyClient.cpp @@ -87,6 +87,12 @@ response::Value Variable::serialize(QueryInput&& inputValue) return result; } +static const std::array, 3> s_valuesOperationType = { + std::make_pair(R"gql(QUERY)gql"sv, OperationType::QUERY), + std::make_pair(R"gql(MUTATION)gql"sv, OperationType::MUTATION), + std::make_pair(R"gql(SUBSCRIPTION)gql"sv, OperationType::SUBSCRIPTION) +}; + template <> OperationType Response::parse(response::Value&& value) { @@ -95,14 +101,8 @@ OperationType Response::parse(response::Value&& value) throw std::logic_error { R"ex(not a valid OperationType value)ex" }; } - static const std::array, 3> s_values = { - std::make_pair(R"gql(QUERY)gql"sv, OperationType::QUERY), - std::make_pair(R"gql(MUTATION)gql"sv, OperationType::MUTATION), - std::make_pair(R"gql(SUBSCRIPTION)gql"sv, OperationType::SUBSCRIPTION) - }; - const auto result = internal::sorted_map_lookup( - s_values, + s_valuesOperationType, std::string_view { value.get() }); if (!result) @@ -162,6 +162,251 @@ response::Value serializeVariables(Variables&& variables) return result; } +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, + Member_relay, + Member_relay_data, + Member_relay_errors, + Member_relay_errors_0, + Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + case impl::VisitorState::Member_relay: + _pimpl->state = impl::VisitorState::Start; + _pimpl->response.relay = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_relay_data: + _pimpl->state = impl::VisitorState::Member_relay; + _pimpl->response.relay.data = ModifiedResponse::parse(response::Value { *value }); + break; + + case impl::VisitorState::Member_relay_errors_0: + _pimpl->response.relay.errors->push_back(ModifiedResponse::parse(response::Value { *value })); + break; + + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_relay_errors_0: + _pimpl->response.relay.errors->reserve(count); + break; + + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_relay_errors_0: + _pimpl->response.relay.errors->push_back(std::make_optional({})); + break; + + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Start: + if (key == "relay"sv) + { + _pimpl->state = impl::VisitorState::Member_relay; + } + break; + + case impl::VisitorState::Member_relay: + if (key == "data"sv) + { + _pimpl->state = impl::VisitorState::Member_relay_data; + } + else if (key == "errors"sv) + { + _pimpl->state = impl::VisitorState::Member_relay_errors; + } + break; + + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_relay_errors: + _pimpl->state = impl::VisitorState::Member_relay_errors_0; + _pimpl->response.relay.errors = std::make_optional>>({}); + break; + + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_relay_errors_0: + _pimpl->state = impl::VisitorState::Member_relay; + break; + + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_relay_data: + _pimpl->state = impl::VisitorState::Member_relay; + _pimpl->response.relay.data = std::nullopt; + break; + + case impl::VisitorState::Member_relay_errors_0: + _pimpl->response.relay.errors->push_back(std::nullopt); + break; + + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + { + case impl::VisitorState::Member_relay_data: + _pimpl->state = impl::VisitorState::Member_relay; + _pimpl->response.relay.data = std::move(value); + break; + + case impl::VisitorState::Member_relay_errors_0: + _pimpl->response.relay.errors->push_back(std::move(value)); + break; + + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + { + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::client; diff --git a/samples/proxy/query/ProxyClient.h b/samples/proxy/query/ProxyClient.h index 58669b8f..01c01ca4 100644 --- a/samples/proxy/query/ProxyClient.h +++ b/samples/proxy/query/ProxyClient.h @@ -76,6 +76,37 @@ struct [[nodiscard("unnecessary construction")]] Response relay_QueryResults relay {}; }; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -89,6 +120,7 @@ struct Traits [[nodiscard("unnecessary conversion")]] static response::Value serializeVariables(Variables&& variables); using Response = relayQuery::Response; + using ResponseVisitor = relayQuery::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; diff --git a/samples/proxy/query/ProxyClient.ixx b/samples/proxy/query/ProxyClient.ixx index d83227a1..51560939 100644 --- a/samples/proxy/query/ProxyClient.ixx +++ b/samples/proxy/query/ProxyClient.ixx @@ -38,6 +38,7 @@ using relayQuery::Variables; using relayQuery::serializeVariables; using relayQuery::Response; +using relayQuery::ResponseVisitor; using relayQuery::parseResponse; using relayQuery::Traits; diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 3b37757e..9108e154 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -478,6 +478,37 @@ using graphql::)cpp" headerFile << R"cpp(}; +class ResponseVisitor + : public std::enable_shared_from_this +{ +public: + ResponseVisitor() noexcept; + ~ResponseVisitor(); + + void add_value(std::shared_ptr&&); + void reserve(std::size_t count); + void start_object(); + void add_member(std::string&& key); + void end_object(); + void start_array(); + void end_array(); + void add_null(); + void add_string(std::string&& value); + void add_enum(std::string&& value); + void add_id(response::IdType&& value); + void add_bool(bool value); + void add_int(int value); + void add_float(double value); + void complete(); + + Response response(); + +private: + struct impl; + + std::unique_ptr _pimpl; +}; + [[nodiscard("unnecessary conversion")]] Response parseResponse(response::Value&& response); struct Traits @@ -500,6 +531,8 @@ struct Traits headerFile << R"cpp( using Response = )cpp" << _requestLoader.getOperationNamespace(operation) << R"cpp(::Response; + using ResponseVisitor = )cpp" + << _requestLoader.getOperationNamespace(operation) << R"cpp(::ResponseVisitor; [[nodiscard("unnecessary conversion")]] static Response parseResponse(response::Value&& response); }; @@ -821,6 +854,8 @@ using )cpp" << operationNamespace pendingSeparator.reset(); moduleFile << R"cpp(using )cpp" << operationNamespace << R"cpp(::Response; +using )cpp" << operationNamespace + << R"cpp(::ResponseVisitor; using )cpp" << operationNamespace << R"cpp(::parseResponse; @@ -1134,8 +1169,7 @@ using namespace )cpp" << _schemaLoader.getSchemaNamespace() sourceFile << R"cpp(template <> response::Value Variable<)cpp" - << cppType << R"cpp(>::serialize()cpp" << cppType - << R"cpp(&& inputValue) + << cppType << R"cpp(>::serialize()cpp" << cppType << R"cpp(&& inputValue) { response::Value result { response::Type::Map }; @@ -1186,19 +1220,9 @@ using namespace )cpp" << _schemaLoader.getSchemaNamespace() const auto& enumValues = enumType->enumValues(); - sourceFile << R"cpp(template <> -)cpp" << cppType << R"cpp( Response<)cpp" - << cppType << R"cpp(>::parse(response::Value&& value) -{ - if (!value.maybe_enum()) - { - throw std::logic_error { R"ex(not a valid )cpp" - << enumType->name() << R"cpp( value)ex" }; - } - - static const std::array, )cpp" << enumValues.size() - << R"cpp(> s_values = {)cpp"; + sourceFile << R"cpp(static const std::array, )cpp" << enumValues.size() << R"cpp(> s_values)cpp" << cppType + << R"cpp( = {)cpp"; std::vector> sortedValues( enumValues.size()); @@ -1224,17 +1248,28 @@ using namespace )cpp" << _schemaLoader.getSchemaNamespace() firstValue = false; sourceFile << R"cpp( - std::make_pair(R"gql()cpp" + std::make_pair(R"gql()cpp" << enumValue.first << R"cpp()gql"sv, )cpp" << cppType << R"cpp(::)cpp" << enumValue.second << R"cpp())cpp"; pendingSeparator.add(); } pendingSeparator.reset(); - sourceFile << R"cpp( }; + sourceFile << R"cpp(}; + +template <> +)cpp" << cppType << R"cpp( Response<)cpp" + << cppType << R"cpp(>::parse(response::Value&& value) +{ + if (!value.maybe_enum()) + { + throw std::logic_error { R"ex(not a valid )cpp" + << enumType->name() << R"cpp( value)ex" }; + } const auto result = internal::sorted_map_lookup( - s_values, + s_values)cpp" << cppType + << R"cpp(, std::string_view { value.get() }); if (!result) @@ -1316,6 +1351,282 @@ response::Value serializeVariables(Variables&& variables) } sourceFile << R"cpp( +struct ResponseVisitor::impl +{ + enum class VisitorState + { + Start, +)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorStates(sourceFile, responseField); + } + + sourceFile << R"cpp( Complete, + }; + + VisitorState state { VisitorState::Start }; + Response response {}; +}; + +ResponseVisitor::ResponseVisitor() noexcept + : _pimpl { std::make_unique() } +{ +} + +ResponseVisitor::~ResponseVisitor() +{ +} + +void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorAddValue(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorReserve(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::start_object() +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorStartObject(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) +{ + switch (_pimpl->state) + {)cpp"; + + outputResponseFieldVisitorAddMember(sourceFile, responseType.fields); + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::end_object() +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorEndObject(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::start_array() +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorStartArray(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::end_array() +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorEndArray(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::add_null() +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorAddNull(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorAddString(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) +{ + using namespace graphql::client; + + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorAddEnum(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorAddId(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::add_bool([[maybe_unused]] bool value) +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorAddBool(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::add_int([[maybe_unused]] int value) +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorAddInt(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::add_float([[maybe_unused]] double value) +{ + switch (_pimpl->state) + {)cpp"; + + for (const auto& responseField : responseType.fields) + { + outputResponseFieldVisitorAddFloat(sourceFile, responseField); + } + + sourceFile << R"cpp( + default: + break; + } +} + +void ResponseVisitor::complete() +{ + _pimpl->state = impl::VisitorState::Complete; +} + +Response ResponseVisitor::response() +{ + Response response {}; + + switch (_pimpl->state) + { + case impl::VisitorState::Complete: + _pimpl->state = impl::VisitorState::Start; + std::swap(_pimpl->response, response); + break; + + default: + break; + } + + return response; +} + Response parseResponse(response::Value&& response) { using namespace graphql::)cpp" @@ -1581,6 +1892,1360 @@ std::string Generator::getTypeModifierList(const TypeModifierStack& modifiers) n return oss.str(); } +void Generator::outputResponseFieldVisitorStates(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parent /* = {} */) const noexcept +{ + auto state = + std::format("{}_{}", parent.empty() ? R"cpp(Member)cpp"sv : parent, responseField.cppName); + + sourceFile << R"cpp( )cpp" << state << R"cpp(, +)cpp"; + + std::size_t arrayDimensions = 0; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + case service::TypeModifier::Nullable: + break; + + case service::TypeModifier::List: + state = std::format("{}_{}", state, arrayDimensions++); + sourceFile << R"cpp( )cpp" << state << R"cpp(, +)cpp"; + break; + } + } + + std::unordered_set fieldNames; + + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + { + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorStates(sourceFile, field, state); + } + } + + break; + } + + default: + break; + } +} + +void Generator::outputResponseFieldVisitorAddValue(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState /* = {} */, + std::string_view parentAccessor /* = {} */, + std::string_view parentCppType /* = {} */) const noexcept +{ + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + responseField.cppName); + auto accessor = std::format("{}{}", parentAccessor, responseField.cppName); + auto cppType = getResponseFieldCppType(responseField, + parentCppType.empty() ? R"cpp(Response)cpp"sv : parentCppType); + + bool isNullable = false; + std::size_t arrayDimensions = 0; + std::optional lastNullableDimension {}; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + isNullable = true; + break; + + case service::TypeModifier::List: + if (isNullable) + { + lastNullableDimension = arrayDimensions; + isNullable = false; + } + + state = std::format("{}_{}", state, arrayDimensions++); + break; + } + } + + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << state << R"cpp(:)cpp"; + + if (arrayDimensions == 0) + { + sourceFile << R"cpp( + _pimpl->state = impl::VisitorState::)cpp" + << (parentState.empty() ? "Start"sv : parentState) << R"cpp(;)cpp"; + } + + sourceFile << R"cpp( + _pimpl->response.)cpp" + << accessor; + + if (arrayDimensions > 0) + { + sourceFile << ((lastNullableDimension && *lastNullableDimension + 1 == arrayDimensions) + ? R"cpp(->)cpp" + : R"cpp(.)cpp") + << R"cpp(push_back()cpp"; + } + else + { + sourceFile << R"cpp( = )cpp"; + } + + sourceFile << R"cpp(ModifiedResponse<)cpp" << cppType << R"cpp(>::parse)cpp"; + + if (arrayDimensions > 0) + { + TypeModifierStack skippedModifiers; + + skippedModifiers.reserve(responseField.modifiers.size() - arrayDimensions); + std::ranges::copy(std::views::all(responseField.modifiers) | std::views::reverse + | std::views::take_while([](auto modifier) noexcept { + return modifier != service::TypeModifier::List; + }) + | std::views::reverse, + std::back_inserter(skippedModifiers)); + sourceFile << getTypeModifierList(skippedModifiers); + } + else + { + sourceFile << getTypeModifierList(responseField.modifiers); + } + + sourceFile << R"cpp((response::Value { *value }))cpp"; + + if (arrayDimensions > 0) + { + sourceFile << R"cpp())cpp"; + } + + sourceFile << R"cpp(; + break; +)cpp"; + + std::unordered_set fieldNames; + + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + { + bool dereference = true; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + accessor.append(R"cpp(->)cpp"); + dereference = false; + break; + + case service::TypeModifier::List: + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + accessor.append(R"cpp(back())cpp"); + dereference = true; + break; + } + } + + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorAddValue(sourceFile, field, state, accessor, cppType); + } + } + + break; + } + + default: + break; + } +} + +void Generator::outputResponseFieldVisitorReserve(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState /* = {} */, + std::string_view parentAccessor /* = {} */, + std::string_view parentCppType /* = {} */) const noexcept +{ + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + responseField.cppName); + auto accessor = std::format("{}{}", parentAccessor, responseField.cppName); + auto cppType = getResponseFieldCppType(responseField, + parentCppType.empty() ? R"cpp(Response)cpp"sv : parentCppType); + + std::size_t arrayDimensions = 0; + bool dereference = true; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + accessor.append(R"cpp(->)cpp"); + dereference = false; + break; + + case service::TypeModifier::List: + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + state = std::format("{}_{}", state, arrayDimensions++); + + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << state << R"cpp(: + _pimpl->response.)cpp" + << accessor << R"cpp(reserve(count); + break; +)cpp"; + + accessor.append(R"cpp(back())cpp"); + dereference = true; + break; + } + } + + std::unordered_set fieldNames; + + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + { + dereference = true; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + accessor.append(R"cpp(->)cpp"); + dereference = false; + break; + + case service::TypeModifier::List: + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + accessor.append(R"cpp(back())cpp"); + dereference = true; + break; + } + } + + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorReserve(sourceFile, field, state, accessor, cppType); + } + } + + break; + } + + default: + break; + } +} + +void Generator::outputResponseFieldVisitorStartObject(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState /* = {} */, + std::string_view parentAccessor /* = {} */, + std::string_view parentCppType /* = {} */) const noexcept +{ + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + responseField.cppName); + auto accessor = std::format("{}{}", parentAccessor, responseField.cppName); + auto cppType = getResponseFieldCppType(responseField, + parentCppType.empty() ? R"cpp(Response)cpp"sv : parentCppType); + + bool isNullable = false; + std::size_t arrayDimensions = 0; + std::optional lastNullableDimension {}; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + isNullable = true; + break; + + case service::TypeModifier::List: + if (isNullable) + { + lastNullableDimension = arrayDimensions; + isNullable = false; + } + + state = std::format("{}_{}", state, arrayDimensions++); + break; + } + } + + if (isNullable && arrayDimensions == 0) + { + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + break; + + default: + isNullable = false; + break; + } + } + + if (isNullable || arrayDimensions > 0) + { + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << state << R"cpp(: + _pimpl->response.)cpp" + << accessor; + + if (arrayDimensions > 0) + { + sourceFile << ((lastNullableDimension && *lastNullableDimension + 1 == arrayDimensions) + ? R"cpp(->)cpp" + : R"cpp(.)cpp") + << R"cpp(push_back()cpp"; + } + else + { + sourceFile << R"cpp( = )cpp"; + } + + if (isNullable) + { + sourceFile << R"cpp(std::make_optional<)cpp" << cppType << R"cpp(>({}))cpp"; + } + else + { + sourceFile << R"cpp({})cpp"; + } + + if (arrayDimensions > 0) + { + sourceFile << R"cpp())cpp"; + } + + sourceFile << R"cpp(; + break; +)cpp"; + } + + std::unordered_set fieldNames; + + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + { + bool dereference = true; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + accessor.append(R"cpp(->)cpp"); + dereference = false; + break; + + case service::TypeModifier::List: + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + accessor.append(R"cpp(back())cpp"); + dereference = true; + break; + } + } + + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorStartObject(sourceFile, + field, + state, + accessor, + cppType); + } + } + + break; + } + + default: + break; + } +} + +void Generator::outputResponseFieldVisitorAddMember(std::ostream& sourceFile, + const ResponseFieldList& children, std::string_view parentState /* = {} */) const noexcept +{ + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << (parentState.empty() ? R"cpp(Start)cpp"sv : parentState) << R"cpp(: + )cpp"; + + std::unordered_set fieldNames; + bool firstField = true; + + for (const auto& field : children) + { + if (!fieldNames.emplace(field.name).second) + { + continue; + } + + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + field.cppName); + + if (!firstField) + { + sourceFile << R"cpp(else )cpp"; + } + + firstField = false; + + sourceFile << R"cpp(if (key == ")cpp" << field.name << R"cpp("sv) + { + _pimpl->state = impl::VisitorState::)cpp" + << state << R"cpp(; + } + )cpp"; + } + + sourceFile << R"cpp(break; +)cpp"; + + fieldNames.clear(); + + for (const auto& field : children) + { + switch (field.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + break; + + default: + continue; + } + + if (!fieldNames.emplace(field.name).second) + { + continue; + } + + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + field.cppName); + std::size_t arrayDimensions = 0; + + for (auto modifier : field.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + case service::TypeModifier::Nullable: + break; + + case service::TypeModifier::List: + state = std::format("{}_{}", state, arrayDimensions++); + break; + } + } + + outputResponseFieldVisitorAddMember(sourceFile, field.children, state); + } +} + +void Generator::outputResponseFieldVisitorEndObject(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState /* = {} */) const noexcept +{ + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + break; + + default: + return; + } + + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + responseField.cppName); + + std::size_t arrayDimensions = 0; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + case service::TypeModifier::Nullable: + break; + + case service::TypeModifier::List: + state = std::format("{}_{}", state, arrayDimensions++); + break; + } + } + + std::unordered_set fieldNames; + + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorEndObject(sourceFile, field, state); + } + } + + if (!parentState.empty() && (arrayDimensions == 0)) + { + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << state << R"cpp(: + _pimpl->state = impl::VisitorState::)cpp" + << parentState << R"cpp(; + break; +)cpp"; + } +} + +void Generator::outputResponseFieldVisitorStartArray(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState /* = {} */, + std::string_view parentAccessor /* = {} */, + std::string_view parentCppType /* = {} */) const noexcept +{ + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + responseField.cppName); + auto accessor = std::format("{}{}", parentAccessor, responseField.cppName); + auto cppType = getResponseFieldCppType(responseField, + parentCppType.empty() ? R"cpp(Response)cpp"sv : parentCppType); + + bool dereference = true; + std::size_t arrayDimensions = 0; + std::size_t skipModifiers = 0; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + dereference = false; + break; + + case service::TypeModifier::List: + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << state << R"cpp(:)cpp"; + + state = std::format("{}_{}", state, arrayDimensions++); + + sourceFile << R"cpp( + _pimpl->state = impl::VisitorState::)cpp" + << state << R"cpp(;)cpp"; + + if (!dereference) + { + sourceFile << R"cpp( + _pimpl->response.)cpp" + << accessor; + + if (arrayDimensions > 1) + { + sourceFile << R"cpp(push_back()cpp"; + } + else + { + sourceFile << R"cpp( = )cpp"; + } + + TypeModifierStack skippedModifiers; + + skippedModifiers.reserve(responseField.modifiers.size() - skipModifiers); + std::ranges::copy( + std::views::all(responseField.modifiers) | std::views::drop(skipModifiers), + std::back_inserter(skippedModifiers)); + + sourceFile << R"cpp(std::make_optional<)cpp" + << RequestLoader::getOutputCppType(cppType, skippedModifiers) + << R"cpp(>({}))cpp"; + + if (arrayDimensions > 1) + { + sourceFile << R"cpp();)cpp"; + } + else + { + sourceFile << R"cpp(;)cpp"; + } + } + + sourceFile << R"cpp( + break; +)cpp"; + + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + else + { + accessor.append(R"cpp(->)cpp"); + } + + accessor.append(R"cpp(back())cpp"); + dereference = true; + break; + } + + ++skipModifiers; + } + + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + std::unordered_set fieldNames; + + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + { + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorStartArray(sourceFile, + field, + state, + accessor, + cppType); + } + } + + break; + } + + default: + break; + } +} + +void Generator::outputResponseFieldVisitorEndArray(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState /* = {} */) const noexcept +{ + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + responseField.cppName); + + std::size_t arrayDimensions = 0; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + case service::TypeModifier::Nullable: + break; + + case service::TypeModifier::List: + { + auto child = std::format("{}_{}", state, arrayDimensions++); + std::string_view parent { state }; + + if (arrayDimensions == 1) + { + parent = parentState.empty() ? "Start"sv : parentState; + } + + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << child << R"cpp(: + _pimpl->state = impl::VisitorState::)cpp" + << parent << R"cpp(; + break; +)cpp"; + + state = std::move(child); + break; + } + } + } + + std::unordered_set fieldNames; + + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorEndArray(sourceFile, field, state); + } + } +} + +void Generator::outputResponseFieldVisitorAddNull(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState /* = {} */, + std::string_view parentAccessor /* = {} */) const noexcept +{ + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + responseField.cppName); + auto accessor = std::format("{}{}", parentAccessor, responseField.cppName); + + bool isNullable = false; + std::size_t arrayDimensions = 0; + std::optional lastNullableDimension {}; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + isNullable = true; + break; + + case service::TypeModifier::List: + if (isNullable) + { + lastNullableDimension = arrayDimensions; + isNullable = false; + } + + state = std::format("{}_{}", state, arrayDimensions++); + break; + } + } + + if (isNullable) + { + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << state << R"cpp(:)cpp"; + + if (arrayDimensions == 0) + { + sourceFile << R"cpp( + _pimpl->state = impl::VisitorState::)cpp" + << (parentState.empty() ? "Start"sv : parentState) << R"cpp(;)cpp"; + } + + sourceFile << R"cpp( + _pimpl->response.)cpp" + << accessor; + + if (arrayDimensions > 0) + { + sourceFile << ((lastNullableDimension && *lastNullableDimension + 1 == arrayDimensions) + ? R"cpp(->)cpp" + : R"cpp(.)cpp") + << R"cpp(push_back()cpp"; + } + else + { + sourceFile << R"cpp( = )cpp"; + } + + sourceFile << R"cpp(std::nullopt)cpp"; + + if (arrayDimensions > 0) + { + sourceFile << R"cpp())cpp"; + } + + sourceFile << R"cpp(; + break; +)cpp"; + } + + std::unordered_set fieldNames; + + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + { + bool dereference = true; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + accessor.append(R"cpp(->)cpp"); + dereference = false; + break; + + case service::TypeModifier::List: + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + accessor.append(R"cpp(back())cpp"); + dereference = true; + break; + } + } + + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorAddNull(sourceFile, field, state, accessor); + } + } + + break; + } + + default: + break; + } +} + +void Generator::outputResponseFieldVisitorAddMovedValue(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view movedCppType, + std::string_view parentState /* = {} */, + std::string_view parentAccessor /* = {} */) const noexcept +{ + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + responseField.cppName); + auto accessor = std::format("{}{}", parentAccessor, responseField.cppName); + + bool isNullable = false; + std::size_t arrayDimensions = 0; + std::optional lastNullableDimension {}; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + isNullable = true; + break; + + case service::TypeModifier::List: + if (isNullable) + { + lastNullableDimension = arrayDimensions; + isNullable = false; + } + + state = std::format("{}_{}", state, arrayDimensions++); + break; + } + } + + if (getResponseFieldCppType(responseField) == movedCppType) + { + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << state << R"cpp(:)cpp"; + + if (arrayDimensions == 0) + { + sourceFile << R"cpp( + _pimpl->state = impl::VisitorState::)cpp" + << (parentState.empty() ? "Start"sv : parentState) << R"cpp(;)cpp"; + } + + sourceFile << R"cpp( + _pimpl->response.)cpp" + << accessor; + + if (arrayDimensions > 0) + { + sourceFile << ((lastNullableDimension && *lastNullableDimension + 1 == arrayDimensions) + ? R"cpp(->)cpp" + : R"cpp(.)cpp") + << R"cpp(push_back()cpp"; + } + else + { + sourceFile << R"cpp( = )cpp"; + } + + sourceFile << R"cpp(std::move(value))cpp"; + + if (arrayDimensions > 0) + { + sourceFile << R"cpp())cpp"; + } + + sourceFile << R"cpp(; + break; +)cpp"; + } + + std::unordered_set fieldNames; + + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + { + bool dereference = true; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + accessor.append(R"cpp(->)cpp"); + dereference = false; + break; + + case service::TypeModifier::List: + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + accessor.append(R"cpp(back())cpp"); + dereference = true; + break; + } + } + + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorAddMovedValue(sourceFile, + field, + movedCppType, + state, + accessor); + } + } + + break; + } + + default: + break; + } +} + +void Generator::outputResponseFieldVisitorAddString( + std::ostream& sourceFile, const ResponseField& responseField) const noexcept +{ + outputResponseFieldVisitorAddMovedValue(sourceFile, responseField, R"cpp(std::string)cpp"sv); +} + +void Generator::outputResponseFieldVisitorAddEnum(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view parentState /* = {} */, + std::string_view parentAccessor /* = {} */, + std::string_view parentCppType /* = {} */) const noexcept +{ + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + responseField.cppName); + auto accessor = std::format("{}{}", parentAccessor, responseField.cppName); + auto cppType = getResponseFieldCppType(responseField, + parentCppType.empty() ? R"cpp(Response)cpp"sv : parentCppType); + + bool isNullable = false; + std::size_t arrayDimensions = 0; + std::optional lastNullableDimension {}; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + isNullable = true; + break; + + case service::TypeModifier::List: + if (isNullable) + { + lastNullableDimension = arrayDimensions; + isNullable = false; + } + + state = std::format("{}_{}", state, arrayDimensions++); + break; + } + } + + if (responseField.type->kind() == introspection::TypeKind::ENUM) + { + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << state << R"cpp(:)cpp"; + + if (arrayDimensions == 0) + { + sourceFile << R"cpp( + _pimpl->state = impl::VisitorState::)cpp" + << (parentState.empty() ? "Start"sv : parentState) << R"cpp(;)cpp"; + } + + sourceFile << R"cpp( + if (const auto enumValue = internal::sorted_map_lookup(s_values)cpp" + << cppType << R"cpp(, std::string_view { value })) + { + _pimpl->response.)cpp" + << accessor; + + if (arrayDimensions > 0) + { + sourceFile << ((lastNullableDimension && *lastNullableDimension + 1 == arrayDimensions) + ? R"cpp(->)cpp" + : R"cpp(.)cpp") + << R"cpp(push_back()cpp"; + } + else + { + sourceFile << R"cpp( = )cpp"; + } + + sourceFile << R"cpp(*enumValue)cpp"; + + if (arrayDimensions > 0) + { + sourceFile << R"cpp())cpp"; + } + + sourceFile << R"cpp(; + } + break; +)cpp"; + } + + std::unordered_set fieldNames; + + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + { + bool dereference = true; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + accessor.append(R"cpp(->)cpp"); + dereference = false; + break; + + case service::TypeModifier::List: + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + accessor.append(R"cpp(back())cpp"); + dereference = true; + break; + } + } + + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorAddEnum(sourceFile, field, state, accessor, cppType); + } + } + + break; + } + + default: + break; + } +} + +void Generator::outputResponseFieldVisitorAddId( + std::ostream& sourceFile, const ResponseField& responseField) const noexcept +{ + outputResponseFieldVisitorAddMovedValue(sourceFile, + responseField, + R"cpp(response::IdType)cpp"sv); +} + +void Generator::outputResponseFieldVisitorAddCopiedValue(std::ostream& sourceFile, + const ResponseField& responseField, std::string_view copiedCppType, + std::string_view parentState /* = {} */, + std::string_view parentAccessor /* = {} */) const noexcept +{ + auto state = std::format("{}_{}", + parentState.empty() ? R"cpp(Member)cpp"sv : parentState, + responseField.cppName); + auto accessor = std::format("{}{}", parentAccessor, responseField.cppName); + + bool isNullable = false; + std::size_t arrayDimensions = 0; + std::optional lastNullableDimension {}; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + isNullable = true; + break; + + case service::TypeModifier::List: + if (isNullable) + { + lastNullableDimension = arrayDimensions; + isNullable = false; + } + + state = std::format("{}_{}", state, arrayDimensions++); + break; + } + } + + if (getResponseFieldCppType(responseField) == copiedCppType) + { + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << state << R"cpp(:)cpp"; + + if (arrayDimensions == 0) + { + sourceFile << R"cpp( + _pimpl->state = impl::VisitorState::)cpp" + << (parentState.empty() ? "Start"sv : parentState) << R"cpp(;)cpp"; + } + + sourceFile << R"cpp( + _pimpl->response.)cpp" + << accessor; + + if (arrayDimensions > 0) + { + sourceFile << ((lastNullableDimension && *lastNullableDimension + 1 == arrayDimensions) + ? R"cpp(->)cpp" + : R"cpp(.)cpp") + << R"cpp(push_back()cpp"; + } + else + { + sourceFile << R"cpp( = )cpp"; + } + + sourceFile << R"cpp(value)cpp"; + + if (arrayDimensions > 0) + { + sourceFile << R"cpp())cpp"; + } + + sourceFile << R"cpp(; + break; +)cpp"; + } + + std::unordered_set fieldNames; + + switch (responseField.type->kind()) + { + case introspection::TypeKind::OBJECT: + case introspection::TypeKind::INTERFACE: + case introspection::TypeKind::UNION: + { + bool dereference = true; + + for (auto modifier : responseField.modifiers) + { + switch (modifier) + { + case service::TypeModifier::None: + break; + + case service::TypeModifier::Nullable: + accessor.append(R"cpp(->)cpp"); + dereference = false; + break; + + case service::TypeModifier::List: + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + accessor.append(R"cpp(back())cpp"); + dereference = true; + break; + } + } + + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + + for (const auto& field : responseField.children) + { + if (fieldNames.emplace(field.name).second) + { + outputResponseFieldVisitorAddCopiedValue(sourceFile, + field, + copiedCppType, + state, + accessor); + } + } + + break; + } + + default: + break; + } +} + +void Generator::outputResponseFieldVisitorAddBool( + std::ostream& sourceFile, const ResponseField& responseField) const noexcept +{ + outputResponseFieldVisitorAddCopiedValue(sourceFile, responseField, R"cpp(bool)cpp"sv); +} + +void Generator::outputResponseFieldVisitorAddInt( + std::ostream& sourceFile, const ResponseField& responseField) const noexcept +{ + outputResponseFieldVisitorAddCopiedValue(sourceFile, responseField, R"cpp(int)cpp"sv); +} + +void Generator::outputResponseFieldVisitorAddFloat( + std::ostream& sourceFile, const ResponseField& responseField) const noexcept +{ + outputResponseFieldVisitorAddCopiedValue(sourceFile, responseField, R"cpp(double)cpp"sv); +} + } // namespace graphql::generator::client namespace po = boost::program_options; From df8db6a7c55016d88fe3b5bd50627add07e53133 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Wed, 16 Oct 2024 23:49:48 -0700 Subject: [PATCH 092/123] fix: unit test with identical results using visitor --- include/ClientGenerator.h | 33 ++-- samples/client/benchmark/TodayClient.cpp | 16 +- .../client/multiple/MultipleQueriesClient.cpp | 92 ++++++++--- samples/client/mutate/MutateClient.cpp | 4 + .../client/nestedinput/NestedInputClient.cpp | 4 + samples/client/query/QueryClient.cpp | 88 +++++++--- samples/client/subscribe/SubscribeClient.cpp | 4 + samples/proxy/query/ProxyClient.cpp | 6 + src/ClientGenerator.cpp | 154 +++++++++++++++--- test/ClientTests.cpp | 100 ++++++++++++ 10 files changed, 406 insertions(+), 95 deletions(-) diff --git a/include/ClientGenerator.h b/include/ClientGenerator.h index 702184dd..a6109108 100644 --- a/include/ClientGenerator.h +++ b/include/ClientGenerator.h @@ -67,8 +67,9 @@ class [[nodiscard("unnecessary construction")]] Generator void outputResponseFieldVisitorStates(std::ostream& sourceFile, const ResponseField& responseField, std::string_view parent = {}) const noexcept; void outputResponseFieldVisitorAddValue(std::ostream& sourceFile, - const ResponseField& responseField, std::string_view parentState = {}, - std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept; + const ResponseField& responseField, bool arrayElement = false, + std::string_view parentState = {}, std::string_view parentAccessor = {}, + std::string_view parentCppType = {}) const noexcept; void outputResponseFieldVisitorReserve(std::ostream& sourceFile, const ResponseField& responseField, std::string_view parentState = {}, std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept; @@ -76,30 +77,36 @@ class [[nodiscard("unnecessary construction")]] Generator const ResponseField& responseField, std::string_view parentState = {}, std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept; void outputResponseFieldVisitorAddMember(std::ostream& sourceFile, - const ResponseFieldList& children, std::string_view parentState = {}) const noexcept; + const ResponseFieldList& children, bool arrayElement = false, + std::string_view parentState = {}) const noexcept; void outputResponseFieldVisitorEndObject(std::ostream& sourceFile, - const ResponseField& responseField, std::string_view parentState = {}) const noexcept; + const ResponseField& responseField, bool arrayElement = false, + std::string_view parentState = {}) const noexcept; void outputResponseFieldVisitorStartArray(std::ostream& sourceFile, const ResponseField& responseField, std::string_view parentState = {}, std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept; - void outputResponseFieldVisitorEndArray(std::ostream& sourceFile, - const ResponseField& responseField, std::string_view parentState = {}) const noexcept; - void outputResponseFieldVisitorAddNull(std::ostream& sourceFile, - const ResponseField& responseField, std::string_view parentState = {}, - std::string_view parentAccessor = {}) const noexcept; + void outputResponseFieldVisitorEndArray(std::ostream& sourceFilearrayElement, + const ResponseField& responseField, bool arrayElement = false, + std::string_view parentState = {}) const noexcept; + void outputResponseFieldVisitorAddNull(std::ostream& sourceFilearrayElement, + const ResponseField& responseField, bool arrayElement = false, + std::string_view parentState = {}, std::string_view parentAccessor = {}) const noexcept; void outputResponseFieldVisitorAddMovedValue(std::ostream& sourceFile, const ResponseField& responseField, std::string_view movedCppType, - std::string_view parentState = {}, std::string_view parentAccessor = {}) const noexcept; + bool arrayElement = false, std::string_view parentState = {}, + std::string_view parentAccessor = {}) const noexcept; void outputResponseFieldVisitorAddString( std::ostream& sourceFile, const ResponseField& responseField) const noexcept; void outputResponseFieldVisitorAddEnum(std::ostream& sourceFile, - const ResponseField& responseField, std::string_view parentState = {}, - std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept; + const ResponseField& responseField, bool arrayElement = false, + std::string_view parentState = {}, std::string_view parentAccessor = {}, + std::string_view parentCppType = {}) const noexcept; void outputResponseFieldVisitorAddId( std::ostream& sourceFile, const ResponseField& responseField) const noexcept; void outputResponseFieldVisitorAddCopiedValue(std::ostream& sourceFile, const ResponseField& responseField, std::string_view copiedCppType, - std::string_view parentState = {}, std::string_view parentAccessor = {}) const noexcept; + bool arrayElement = false, std::string_view parentState = {}, + std::string_view parentAccessor = {}) const noexcept; void outputResponseFieldVisitorAddBool( std::ostream& sourceFile, const ResponseField& responseField) const noexcept; void outputResponseFieldVisitorAddInt( diff --git a/samples/client/benchmark/TodayClient.cpp b/samples/client/benchmark/TodayClient.cpp index e8e67d9f..72889197 100644 --- a/samples/client/benchmark/TodayClient.cpp +++ b/samples/client/benchmark/TodayClient.cpp @@ -195,6 +195,7 @@ struct ResponseVisitor::impl Member_appointments_pageInfo_hasNextPage, Member_appointments_edges, Member_appointments_edges_0, + Member_appointments_edges_0_, Member_appointments_edges_0_node, Member_appointments_edges_0_node_id, Member_appointments_edges_0_node_when, @@ -242,7 +243,7 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrstate = impl::VisitorState::Member_appointments_edges_0; + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; _pimpl->response.appointments.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); break; @@ -289,6 +290,7 @@ void ResponseVisitor::start_object() switch (_pimpl->state) { case impl::VisitorState::Member_appointments_edges_0: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; _pimpl->response.appointments.edges->push_back(std::make_optional({})); break; @@ -330,7 +332,7 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; - case impl::VisitorState::Member_appointments_edges_0: + case impl::VisitorState::Member_appointments_edges_0_: if (key == "node"sv) { _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; @@ -370,9 +372,17 @@ void ResponseVisitor::end_object() break; case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; + break; + + case impl::VisitorState::Member_appointments_edges_0_: _pimpl->state = impl::VisitorState::Member_appointments_edges_0; break; + case impl::VisitorState::Member_appointments: + _pimpl->state = impl::VisitorState::Start; + break; + default: break; } @@ -414,7 +424,7 @@ void ResponseVisitor::add_null() break; case impl::VisitorState::Member_appointments_edges_0_node: - _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; _pimpl->response.appointments.edges->back()->node = std::nullopt; break; diff --git a/samples/client/multiple/MultipleQueriesClient.cpp b/samples/client/multiple/MultipleQueriesClient.cpp index da1d8b40..93cdd504 100644 --- a/samples/client/multiple/MultipleQueriesClient.cpp +++ b/samples/client/multiple/MultipleQueriesClient.cpp @@ -293,6 +293,7 @@ struct ResponseVisitor::impl Member_appointments, Member_appointments_edges, Member_appointments_edges_0, + Member_appointments_edges_0_, Member_appointments_edges_0_node, Member_appointments_edges_0_node_id, Member_appointments_edges_0_node_subject, @@ -331,7 +332,7 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrstate = impl::VisitorState::Member_appointments_edges_0; + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; _pimpl->response.appointments.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); break; @@ -383,6 +384,7 @@ void ResponseVisitor::start_object() switch (_pimpl->state) { case impl::VisitorState::Member_appointments_edges_0: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; _pimpl->response.appointments.edges->push_back(std::make_optional({})); break; @@ -413,7 +415,7 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; - case impl::VisitorState::Member_appointments_edges_0: + case impl::VisitorState::Member_appointments_edges_0_: if (key == "node"sv) { _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; @@ -453,9 +455,17 @@ void ResponseVisitor::end_object() switch (_pimpl->state) { case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; + break; + + case impl::VisitorState::Member_appointments_edges_0_: _pimpl->state = impl::VisitorState::Member_appointments_edges_0; break; + case impl::VisitorState::Member_appointments: + _pimpl->state = impl::VisitorState::Start; + break; + default: break; } @@ -497,7 +507,7 @@ void ResponseVisitor::add_null() break; case impl::VisitorState::Member_appointments_edges_0_node: - _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; _pimpl->response.appointments.edges->back()->node = std::nullopt; break; @@ -763,6 +773,7 @@ struct ResponseVisitor::impl Member_tasks, Member_tasks_edges, Member_tasks_edges_0, + Member_tasks_edges_0_, Member_tasks_edges_0_node, Member_tasks_edges_0_node_id, Member_tasks_edges_0_node_title, @@ -800,7 +811,7 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrstate = impl::VisitorState::Member_tasks_edges_0; + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_; _pimpl->response.tasks.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); break; @@ -847,6 +858,7 @@ void ResponseVisitor::start_object() switch (_pimpl->state) { case impl::VisitorState::Member_tasks_edges_0: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_; _pimpl->response.tasks.edges->push_back(std::make_optional({})); break; @@ -877,7 +889,7 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; - case impl::VisitorState::Member_tasks_edges_0: + case impl::VisitorState::Member_tasks_edges_0_: if (key == "node"sv) { _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; @@ -913,9 +925,17 @@ void ResponseVisitor::end_object() switch (_pimpl->state) { case impl::VisitorState::Member_tasks_edges_0_node: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_; + break; + + case impl::VisitorState::Member_tasks_edges_0_: _pimpl->state = impl::VisitorState::Member_tasks_edges_0; break; + case impl::VisitorState::Member_tasks: + _pimpl->state = impl::VisitorState::Start; + break; + default: break; } @@ -957,7 +977,7 @@ void ResponseVisitor::add_null() break; case impl::VisitorState::Member_tasks_edges_0_node: - _pimpl->state = impl::VisitorState::Member_tasks_edges_0; + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_; _pimpl->response.tasks.edges->back()->node = std::nullopt; break; @@ -1218,6 +1238,7 @@ struct ResponseVisitor::impl Member_unreadCounts, Member_unreadCounts_edges, Member_unreadCounts_edges_0, + Member_unreadCounts_edges_0_, Member_unreadCounts_edges_0_node, Member_unreadCounts_edges_0_node_id, Member_unreadCounts_edges_0_node_name, @@ -1255,7 +1276,7 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrstate = impl::VisitorState::Member_unreadCounts_edges_0; + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_; _pimpl->response.unreadCounts.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); break; @@ -1302,6 +1323,7 @@ void ResponseVisitor::start_object() switch (_pimpl->state) { case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_; _pimpl->response.unreadCounts.edges->push_back(std::make_optional({})); break; @@ -1332,7 +1354,7 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; - case impl::VisitorState::Member_unreadCounts_edges_0: + case impl::VisitorState::Member_unreadCounts_edges_0_: if (key == "node"sv) { _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; @@ -1368,9 +1390,17 @@ void ResponseVisitor::end_object() switch (_pimpl->state) { case impl::VisitorState::Member_unreadCounts_edges_0_node: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_; + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_: _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; break; + case impl::VisitorState::Member_unreadCounts: + _pimpl->state = impl::VisitorState::Start; + break; + default: break; } @@ -1412,7 +1442,7 @@ void ResponseVisitor::add_null() break; case impl::VisitorState::Member_unreadCounts_edges_0_node: - _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_; _pimpl->response.unreadCounts.edges->back()->node = std::nullopt; break; @@ -1672,6 +1702,7 @@ struct ResponseVisitor::impl Member_testTaskState, Member_anyType, Member_anyType_0, + Member_anyType_0_, Member_anyType_0__typename, Member_anyType_0_id, Member_anyType_0_title, @@ -1712,37 +1743,37 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrstate = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->_typename = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_id: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->id = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_title: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->title = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_isComplete: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->isComplete = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_subject: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->subject = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_when: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->when = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_isNow: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->isNow = ModifiedResponse::parse(response::Value { *value }); break; @@ -1774,6 +1805,7 @@ void ResponseVisitor::start_object() switch (_pimpl->state) { case impl::VisitorState::Member_anyType_0: + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.push_back(std::make_optional({})); break; @@ -1801,7 +1833,7 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; - case impl::VisitorState::Member_anyType_0: + case impl::VisitorState::Member_anyType_0_: if (key == "__typename"sv) { _pimpl->state = impl::VisitorState::Member_anyType_0__typename; @@ -1841,6 +1873,10 @@ void ResponseVisitor::end_object() { switch (_pimpl->state) { + case impl::VisitorState::Member_anyType_0_: + _pimpl->state = impl::VisitorState::Member_anyType_0; + break; + default: break; } @@ -1881,17 +1917,17 @@ void ResponseVisitor::add_null() break; case impl::VisitorState::Member_anyType_0_title: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->title = std::nullopt; break; case impl::VisitorState::Member_anyType_0_subject: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->subject = std::nullopt; break; case impl::VisitorState::Member_anyType_0_when: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->when = std::nullopt; break; @@ -1910,17 +1946,17 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) switch (_pimpl->state) { case impl::VisitorState::Member_anyType_0__typename: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->_typename = std::move(value); break; case impl::VisitorState::Member_anyType_0_title: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->title = std::move(value); break; case impl::VisitorState::Member_anyType_0_subject: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->subject = std::move(value); break; @@ -1958,7 +1994,7 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) switch (_pimpl->state) { case impl::VisitorState::Member_anyType_0_id: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->id = std::move(value); break; @@ -1972,12 +2008,12 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) switch (_pimpl->state) { case impl::VisitorState::Member_anyType_0_isComplete: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->isComplete = value; break; case impl::VisitorState::Member_anyType_0_isNow: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->isNow = value; break; @@ -2338,6 +2374,10 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Member_completedTask; break; + case impl::VisitorState::Member_completedTask: + _pimpl->state = impl::VisitorState::Start; + break; + default: break; } diff --git a/samples/client/mutate/MutateClient.cpp b/samples/client/mutate/MutateClient.cpp index 7d8840bf..bc32c1d3 100644 --- a/samples/client/mutate/MutateClient.cpp +++ b/samples/client/mutate/MutateClient.cpp @@ -401,6 +401,10 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Member_completedTask; break; + case impl::VisitorState::Member_completedTask: + _pimpl->state = impl::VisitorState::Start; + break; + default: break; } diff --git a/samples/client/nestedinput/NestedInputClient.cpp b/samples/client/nestedinput/NestedInputClient.cpp index 9e8d3f90..8e4b4650 100644 --- a/samples/client/nestedinput/NestedInputClient.cpp +++ b/samples/client/nestedinput/NestedInputClient.cpp @@ -466,6 +466,10 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Member_control; break; + case impl::VisitorState::Member_control: + _pimpl->state = impl::VisitorState::Start; + break; + default: break; } diff --git a/samples/client/query/QueryClient.cpp b/samples/client/query/QueryClient.cpp index 50e333d9..072ebec5 100644 --- a/samples/client/query/QueryClient.cpp +++ b/samples/client/query/QueryClient.cpp @@ -456,6 +456,7 @@ struct ResponseVisitor::impl Member_appointments, Member_appointments_edges, Member_appointments_edges_0, + Member_appointments_edges_0_, Member_appointments_edges_0_node, Member_appointments_edges_0_node_id, Member_appointments_edges_0_node_subject, @@ -465,6 +466,7 @@ struct ResponseVisitor::impl Member_tasks, Member_tasks_edges, Member_tasks_edges_0, + Member_tasks_edges_0_, Member_tasks_edges_0_node, Member_tasks_edges_0_node_id, Member_tasks_edges_0_node_title, @@ -473,6 +475,7 @@ struct ResponseVisitor::impl Member_unreadCounts, Member_unreadCounts_edges, Member_unreadCounts_edges_0, + Member_unreadCounts_edges_0_, Member_unreadCounts_edges_0_node, Member_unreadCounts_edges_0_node_id, Member_unreadCounts_edges_0_node_name, @@ -481,6 +484,7 @@ struct ResponseVisitor::impl Member_testTaskState, Member_anyType, Member_anyType_0, + Member_anyType_0_, Member_anyType_0__typename, Member_anyType_0_id, Member_anyType_0_title, @@ -521,7 +525,7 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrstate = impl::VisitorState::Member_appointments_edges_0; + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; _pimpl->response.appointments.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); break; @@ -560,7 +564,7 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrstate = impl::VisitorState::Member_tasks_edges_0; + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_; _pimpl->response.tasks.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); break; @@ -594,7 +598,7 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrstate = impl::VisitorState::Member_unreadCounts_edges_0; + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_; _pimpl->response.unreadCounts.edges->back()->node = ModifiedResponse::parse(response::Value { *value }); break; @@ -628,37 +632,37 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrstate = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->_typename = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_id: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->id = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_title: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->title = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_isComplete: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->isComplete = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_subject: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->subject = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_when: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->when = ModifiedResponse::parse(response::Value { *value }); break; case impl::VisitorState::Member_anyType_0_isNow: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->isNow = ModifiedResponse::parse(response::Value { *value }); break; @@ -702,6 +706,7 @@ void ResponseVisitor::start_object() switch (_pimpl->state) { case impl::VisitorState::Member_appointments_edges_0: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; _pimpl->response.appointments.edges->push_back(std::make_optional({})); break; @@ -710,6 +715,7 @@ void ResponseVisitor::start_object() break; case impl::VisitorState::Member_tasks_edges_0: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_; _pimpl->response.tasks.edges->push_back(std::make_optional({})); break; @@ -718,6 +724,7 @@ void ResponseVisitor::start_object() break; case impl::VisitorState::Member_unreadCounts_edges_0: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_; _pimpl->response.unreadCounts.edges->push_back(std::make_optional({})); break; @@ -726,6 +733,7 @@ void ResponseVisitor::start_object() break; case impl::VisitorState::Member_anyType_0: + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.push_back(std::make_optional({})); break; @@ -772,7 +780,7 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; - case impl::VisitorState::Member_appointments_edges_0: + case impl::VisitorState::Member_appointments_edges_0_: if (key == "node"sv) { _pimpl->state = impl::VisitorState::Member_appointments_edges_0_node; @@ -809,7 +817,7 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; - case impl::VisitorState::Member_tasks_edges_0: + case impl::VisitorState::Member_tasks_edges_0_: if (key == "node"sv) { _pimpl->state = impl::VisitorState::Member_tasks_edges_0_node; @@ -842,7 +850,7 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; - case impl::VisitorState::Member_unreadCounts_edges_0: + case impl::VisitorState::Member_unreadCounts_edges_0_: if (key == "node"sv) { _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_node; @@ -868,7 +876,7 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; - case impl::VisitorState::Member_anyType_0: + case impl::VisitorState::Member_anyType_0_: if (key == "__typename"sv) { _pimpl->state = impl::VisitorState::Member_anyType_0__typename; @@ -909,17 +917,45 @@ void ResponseVisitor::end_object() switch (_pimpl->state) { case impl::VisitorState::Member_appointments_edges_0_node: + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; + break; + + case impl::VisitorState::Member_appointments_edges_0_: _pimpl->state = impl::VisitorState::Member_appointments_edges_0; break; + case impl::VisitorState::Member_appointments: + _pimpl->state = impl::VisitorState::Start; + break; + case impl::VisitorState::Member_tasks_edges_0_node: + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_; + break; + + case impl::VisitorState::Member_tasks_edges_0_: _pimpl->state = impl::VisitorState::Member_tasks_edges_0; break; + case impl::VisitorState::Member_tasks: + _pimpl->state = impl::VisitorState::Start; + break; + case impl::VisitorState::Member_unreadCounts_edges_0_node: + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_; + break; + + case impl::VisitorState::Member_unreadCounts_edges_0_: _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; break; + case impl::VisitorState::Member_unreadCounts: + _pimpl->state = impl::VisitorState::Start; + break; + + case impl::VisitorState::Member_anyType_0_: + _pimpl->state = impl::VisitorState::Member_anyType_0; + break; + default: break; } @@ -987,7 +1023,7 @@ void ResponseVisitor::add_null() break; case impl::VisitorState::Member_appointments_edges_0_node: - _pimpl->state = impl::VisitorState::Member_appointments_edges_0; + _pimpl->state = impl::VisitorState::Member_appointments_edges_0_; _pimpl->response.appointments.edges->back()->node = std::nullopt; break; @@ -1006,7 +1042,7 @@ void ResponseVisitor::add_null() break; case impl::VisitorState::Member_tasks_edges_0_node: - _pimpl->state = impl::VisitorState::Member_tasks_edges_0; + _pimpl->state = impl::VisitorState::Member_tasks_edges_0_; _pimpl->response.tasks.edges->back()->node = std::nullopt; break; @@ -1020,7 +1056,7 @@ void ResponseVisitor::add_null() break; case impl::VisitorState::Member_unreadCounts_edges_0_node: - _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0; + _pimpl->state = impl::VisitorState::Member_unreadCounts_edges_0_; _pimpl->response.unreadCounts.edges->back()->node = std::nullopt; break; @@ -1034,17 +1070,17 @@ void ResponseVisitor::add_null() break; case impl::VisitorState::Member_anyType_0_title: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->title = std::nullopt; break; case impl::VisitorState::Member_anyType_0_subject: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->subject = std::nullopt; break; case impl::VisitorState::Member_anyType_0_when: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->when = std::nullopt; break; @@ -1093,17 +1129,17 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) break; case impl::VisitorState::Member_anyType_0__typename: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->_typename = std::move(value); break; case impl::VisitorState::Member_anyType_0_title: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->title = std::move(value); break; case impl::VisitorState::Member_anyType_0_subject: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->subject = std::move(value); break; @@ -1156,7 +1192,7 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) break; case impl::VisitorState::Member_anyType_0_id: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->id = std::move(value); break; @@ -1180,12 +1216,12 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) break; case impl::VisitorState::Member_anyType_0_isComplete: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->isComplete = value; break; case impl::VisitorState::Member_anyType_0_isNow: - _pimpl->state = impl::VisitorState::Member_anyType_0; + _pimpl->state = impl::VisitorState::Member_anyType_0_; _pimpl->response.anyType.back()->isNow = value; break; diff --git a/samples/client/subscribe/SubscribeClient.cpp b/samples/client/subscribe/SubscribeClient.cpp index daf6e66f..79fa858d 100644 --- a/samples/client/subscribe/SubscribeClient.cpp +++ b/samples/client/subscribe/SubscribeClient.cpp @@ -230,6 +230,10 @@ void ResponseVisitor::end_object() { switch (_pimpl->state) { + case impl::VisitorState::Member_nextAppointment: + _pimpl->state = impl::VisitorState::Start; + break; + default: break; } diff --git a/samples/proxy/query/ProxyClient.cpp b/samples/proxy/query/ProxyClient.cpp index f262a1d8..7286b49f 100644 --- a/samples/proxy/query/ProxyClient.cpp +++ b/samples/proxy/query/ProxyClient.cpp @@ -171,6 +171,7 @@ struct ResponseVisitor::impl Member_relay_data, Member_relay_errors, Member_relay_errors_0, + Member_relay_errors_0_, Complete, }; @@ -230,6 +231,7 @@ void ResponseVisitor::start_object() switch (_pimpl->state) { case impl::VisitorState::Member_relay_errors_0: + _pimpl->state = impl::VisitorState::Member_relay_errors_0_; _pimpl->response.relay.errors->push_back(std::make_optional({})); break; @@ -269,6 +271,10 @@ void ResponseVisitor::end_object() { switch (_pimpl->state) { + case impl::VisitorState::Member_relay: + _pimpl->state = impl::VisitorState::Start; + break; + default: break; } diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 9108e154..feddce14 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -1919,6 +1919,12 @@ void Generator::outputResponseFieldVisitorStates(std::ostream& sourceFile, } } + if (arrayDimensions > 0) + { + sourceFile << R"cpp( )cpp" << state << R"cpp(_, +)cpp"; + } + std::unordered_set fieldNames; switch (responseField.type->kind()) @@ -1944,8 +1950,8 @@ void Generator::outputResponseFieldVisitorStates(std::ostream& sourceFile, } void Generator::outputResponseFieldVisitorAddValue(std::ostream& sourceFile, - const ResponseField& responseField, std::string_view parentState /* = {} */, - std::string_view parentAccessor /* = {} */, + const ResponseField& responseField, bool arrayElement /* = false */, + std::string_view parentState /* = {} */, std::string_view parentAccessor /* = {} */, std::string_view parentCppType /* = {} */) const noexcept { auto state = std::format("{}_{}", @@ -1990,7 +1996,14 @@ void Generator::outputResponseFieldVisitorAddValue(std::ostream& sourceFile, { sourceFile << R"cpp( _pimpl->state = impl::VisitorState::)cpp" - << (parentState.empty() ? "Start"sv : parentState) << R"cpp(;)cpp"; + << (parentState.empty() ? "Start"sv : parentState); + + if (arrayElement) + { + sourceFile << R"cpp(_)cpp"; + } + + sourceFile << R"cpp(;)cpp"; } sourceFile << R"cpp( @@ -2083,7 +2096,12 @@ void Generator::outputResponseFieldVisitorAddValue(std::ostream& sourceFile, { if (fieldNames.emplace(field.name).second) { - outputResponseFieldVisitorAddValue(sourceFile, field, state, accessor, cppType); + outputResponseFieldVisitorAddValue(sourceFile, + field, + arrayDimensions > 0, + state, + accessor, + cppType); } } @@ -2256,7 +2274,16 @@ void Generator::outputResponseFieldVisitorStartObject(std::ostream& sourceFile, { sourceFile << R"cpp( case impl::VisitorState::)cpp" - << state << R"cpp(: + << state << R"cpp(:)cpp"; + + if (arrayDimensions > 0) + { + sourceFile << R"cpp( + _pimpl->state = impl::VisitorState::)cpp" + << state << R"cpp(_;)cpp"; + } + + sourceFile << R"cpp( _pimpl->response.)cpp" << accessor; @@ -2351,11 +2378,19 @@ void Generator::outputResponseFieldVisitorStartObject(std::ostream& sourceFile, } void Generator::outputResponseFieldVisitorAddMember(std::ostream& sourceFile, - const ResponseFieldList& children, std::string_view parentState /* = {} */) const noexcept + const ResponseFieldList& children, bool arrayElement /* = false */, + std::string_view parentState /* = {} */) const noexcept { sourceFile << R"cpp( case impl::VisitorState::)cpp" - << (parentState.empty() ? R"cpp(Start)cpp"sv : parentState) << R"cpp(: + << (parentState.empty() ? R"cpp(Start)cpp"sv : parentState); + + if (arrayElement) + { + sourceFile << R"cpp(_)cpp"; + } + + sourceFile << R"cpp(: )cpp"; std::unordered_set fieldNames; @@ -2429,12 +2464,13 @@ void Generator::outputResponseFieldVisitorAddMember(std::ostream& sourceFile, } } - outputResponseFieldVisitorAddMember(sourceFile, field.children, state); + outputResponseFieldVisitorAddMember(sourceFile, field.children, arrayDimensions > 0, state); } } void Generator::outputResponseFieldVisitorEndObject(std::ostream& sourceFile, - const ResponseField& responseField, std::string_view parentState /* = {} */) const noexcept + const ResponseField& responseField, bool arrayElement /* = false */, + std::string_view parentState /* = {} */) const noexcept { switch (responseField.type->kind()) { @@ -2452,6 +2488,7 @@ void Generator::outputResponseFieldVisitorEndObject(std::ostream& sourceFile, responseField.cppName); std::size_t arrayDimensions = 0; + std::string arrayState; for (auto modifier : responseField.modifiers) { @@ -2473,20 +2510,35 @@ void Generator::outputResponseFieldVisitorEndObject(std::ostream& sourceFile, { if (fieldNames.emplace(field.name).second) { - outputResponseFieldVisitorEndObject(sourceFile, field, state); + outputResponseFieldVisitorEndObject(sourceFile, field, arrayDimensions > 0, state); } } - if (!parentState.empty() && (arrayDimensions == 0)) + if (arrayDimensions > 0) + { + sourceFile << R"cpp( + case impl::VisitorState::)cpp" + << state << R"cpp(_: + _pimpl->state = impl::VisitorState::)cpp" + << state; + } + else { sourceFile << R"cpp( case impl::VisitorState::)cpp" << state << R"cpp(: _pimpl->state = impl::VisitorState::)cpp" - << parentState << R"cpp(; + << (parentState.empty() ? "Start"sv : parentState); + + if (arrayElement) + { + sourceFile << R"cpp(_)cpp"; + } + } + + sourceFile << R"cpp(; break; )cpp"; - } } void Generator::outputResponseFieldVisitorStartArray(std::ostream& sourceFile, @@ -2618,7 +2670,8 @@ void Generator::outputResponseFieldVisitorStartArray(std::ostream& sourceFile, } void Generator::outputResponseFieldVisitorEndArray(std::ostream& sourceFile, - const ResponseField& responseField, std::string_view parentState /* = {} */) const noexcept + const ResponseField& responseField, bool arrayElement /* = false */, + std::string_view parentState /* = {} */) const noexcept { auto state = std::format("{}_{}", parentState.empty() ? R"cpp(Member)cpp"sv : parentState, @@ -2648,7 +2701,14 @@ void Generator::outputResponseFieldVisitorEndArray(std::ostream& sourceFile, case impl::VisitorState::)cpp" << child << R"cpp(: _pimpl->state = impl::VisitorState::)cpp" - << parent << R"cpp(; + << parent; + + if (arrayElement) + { + sourceFile << R"cpp(_)cpp"; + } + + sourceFile << R"cpp(; break; )cpp"; @@ -2664,13 +2724,14 @@ void Generator::outputResponseFieldVisitorEndArray(std::ostream& sourceFile, { if (fieldNames.emplace(field.name).second) { - outputResponseFieldVisitorEndArray(sourceFile, field, state); + outputResponseFieldVisitorEndArray(sourceFile, field, arrayDimensions > 0, state); } } } void Generator::outputResponseFieldVisitorAddNull(std::ostream& sourceFile, - const ResponseField& responseField, std::string_view parentState /* = {} */, + const ResponseField& responseField, bool arrayElement /* = false */, + std::string_view parentState /* = {} */, std::string_view parentAccessor /* = {} */) const noexcept { auto state = std::format("{}_{}", @@ -2715,7 +2776,14 @@ void Generator::outputResponseFieldVisitorAddNull(std::ostream& sourceFile, { sourceFile << R"cpp( _pimpl->state = impl::VisitorState::)cpp" - << (parentState.empty() ? "Start"sv : parentState) << R"cpp(;)cpp"; + << (parentState.empty() ? "Start"sv : parentState); + + if (arrayElement) + { + sourceFile << R"cpp(_)cpp"; + } + + sourceFile << R"cpp(;)cpp"; } sourceFile << R"cpp( @@ -2789,7 +2857,11 @@ void Generator::outputResponseFieldVisitorAddNull(std::ostream& sourceFile, { if (fieldNames.emplace(field.name).second) { - outputResponseFieldVisitorAddNull(sourceFile, field, state, accessor); + outputResponseFieldVisitorAddNull(sourceFile, + field, + arrayDimensions > 0, + state, + accessor); } } @@ -2803,7 +2875,7 @@ void Generator::outputResponseFieldVisitorAddNull(std::ostream& sourceFile, void Generator::outputResponseFieldVisitorAddMovedValue(std::ostream& sourceFile, const ResponseField& responseField, std::string_view movedCppType, - std::string_view parentState /* = {} */, + bool arrayElement /* = false */, std::string_view parentState /* = {} */, std::string_view parentAccessor /* = {} */) const noexcept { auto state = std::format("{}_{}", @@ -2848,7 +2920,14 @@ void Generator::outputResponseFieldVisitorAddMovedValue(std::ostream& sourceFile { sourceFile << R"cpp( _pimpl->state = impl::VisitorState::)cpp" - << (parentState.empty() ? "Start"sv : parentState) << R"cpp(;)cpp"; + << (parentState.empty() ? "Start"sv : parentState); + + if (arrayElement) + { + sourceFile << R"cpp(_)cpp"; + } + + sourceFile << R"cpp(;)cpp"; } sourceFile << R"cpp( @@ -2925,6 +3004,7 @@ void Generator::outputResponseFieldVisitorAddMovedValue(std::ostream& sourceFile outputResponseFieldVisitorAddMovedValue(sourceFile, field, movedCppType, + arrayDimensions > 0, state, accessor); } @@ -2945,8 +3025,8 @@ void Generator::outputResponseFieldVisitorAddString( } void Generator::outputResponseFieldVisitorAddEnum(std::ostream& sourceFile, - const ResponseField& responseField, std::string_view parentState /* = {} */, - std::string_view parentAccessor /* = {} */, + const ResponseField& responseField, bool arrayElement /* = false */, + std::string_view parentState /* = {} */, std::string_view parentAccessor /* = {} */, std::string_view parentCppType /* = {} */) const noexcept { auto state = std::format("{}_{}", @@ -2993,7 +3073,14 @@ void Generator::outputResponseFieldVisitorAddEnum(std::ostream& sourceFile, { sourceFile << R"cpp( _pimpl->state = impl::VisitorState::)cpp" - << (parentState.empty() ? "Start"sv : parentState) << R"cpp(;)cpp"; + << (parentState.empty() ? "Start"sv : parentState); + + if (arrayElement) + { + sourceFile << R"cpp(_)cpp"; + } + + sourceFile << R"cpp(;)cpp"; } sourceFile << R"cpp( @@ -3071,7 +3158,12 @@ void Generator::outputResponseFieldVisitorAddEnum(std::ostream& sourceFile, { if (fieldNames.emplace(field.name).second) { - outputResponseFieldVisitorAddEnum(sourceFile, field, state, accessor, cppType); + outputResponseFieldVisitorAddEnum(sourceFile, + field, + arrayDimensions > 0, + state, + accessor, + cppType); } } @@ -3093,7 +3185,7 @@ void Generator::outputResponseFieldVisitorAddId( void Generator::outputResponseFieldVisitorAddCopiedValue(std::ostream& sourceFile, const ResponseField& responseField, std::string_view copiedCppType, - std::string_view parentState /* = {} */, + bool arrayElement /* = false */, std::string_view parentState /* = {} */, std::string_view parentAccessor /* = {} */) const noexcept { auto state = std::format("{}_{}", @@ -3138,7 +3230,14 @@ void Generator::outputResponseFieldVisitorAddCopiedValue(std::ostream& sourceFil { sourceFile << R"cpp( _pimpl->state = impl::VisitorState::)cpp" - << (parentState.empty() ? "Start"sv : parentState) << R"cpp(;)cpp"; + << (parentState.empty() ? "Start"sv : parentState); + + if (arrayElement) + { + sourceFile << R"cpp(_)cpp"; + } + + sourceFile << R"cpp(;)cpp"; } sourceFile << R"cpp( @@ -3215,6 +3314,7 @@ void Generator::outputResponseFieldVisitorAddCopiedValue(std::ostream& sourceFil outputResponseFieldVisitorAddCopiedValue(sourceFile, field, copiedCppType, + arrayDimensions > 0, state, accessor); } diff --git a/test/ClientTests.cpp b/test/ClientTests.cpp index 031e4c47..da28230b 100644 --- a/test/ClientTests.cpp +++ b/test/ClientTests.cpp @@ -137,6 +137,106 @@ TEST_F(ClientCase, QueryEverything) } } +TEST_F(ClientCase, QueryEverythingWithVisitor) +{ + using namespace query::client::query::Query; + + auto query = GetRequestObject(); + + response::Value variables(response::Type::Map); + auto state = std::make_shared(1); + auto result = + _mockService->service->visit({ query, {}, std::move(variables), std::launch::async, state }) + .get(); + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) + << "today service lazy loads the appointments and caches the result"; + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) + << "today service lazy loads the tasks and caches the result"; + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) + << "today service lazy loads the unreadCounts and caches the result"; + EXPECT_EQ(std::size_t { 1 }, state->appointmentsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->tasksRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->unreadCountsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; + + try + { + auto visitor = std::make_shared(); + auto responseVisitor = std::make_shared(visitor); + std::move(result.data).visit(responseVisitor); + const auto response = visitor->response(); + + EXPECT_EQ(std::size_t { 0 }, result.errors.size()) << "no errors expected"; + + ASSERT_TRUE(response.appointments.edges.has_value()) << "appointments should be set"; + ASSERT_EQ(std::size_t { 1 }, response.appointments.edges->size()) + << "appointments should have 1 entry"; + ASSERT_TRUE((*response.appointments.edges)[0].has_value()) << "edge should be set"; + const auto& appointmentNode = (*response.appointments.edges)[0]->node; + ASSERT_TRUE(appointmentNode.has_value()) << "node should be set"; + EXPECT_EQ(today::getFakeAppointmentId(), appointmentNode->id) + << "id should match in base64 encoding"; + ASSERT_TRUE(appointmentNode->subject.has_value()) << "subject should be set"; + EXPECT_EQ("Lunch?", *(appointmentNode->subject)) << "subject should match"; + ASSERT_TRUE(appointmentNode->when.has_value()) << "when should be set"; + EXPECT_EQ("tomorrow", appointmentNode->when->get()) << "when should match"; + EXPECT_FALSE(appointmentNode->isNow) << "isNow should match"; + EXPECT_EQ("Appointment", appointmentNode->_typename) << "__typename should match"; + + ASSERT_TRUE(response.tasks.edges.has_value()) << "tasks should be set"; + ASSERT_EQ(std::size_t { 1 }, response.tasks.edges->size()) << "tasks should have 1 entry"; + ASSERT_TRUE((*response.tasks.edges)[0].has_value()) << "edge should be set"; + const auto& taskNode = (*response.tasks.edges)[0]->node; + ASSERT_TRUE(taskNode.has_value()) << "node should be set"; + EXPECT_EQ(today::getFakeTaskId(), taskNode->id) << "id should match in base64 encoding"; + ASSERT_TRUE(taskNode->title.has_value()) << "subject should be set"; + EXPECT_EQ("Don't forget", *(taskNode->title)) << "title should match"; + EXPECT_TRUE(taskNode->isComplete) << "isComplete should match"; + EXPECT_EQ("Task", taskNode->_typename) << "__typename should match"; + + ASSERT_TRUE(response.unreadCounts.edges.has_value()) << "unreadCounts should be set"; + ASSERT_EQ(std::size_t { 1 }, response.unreadCounts.edges->size()) + << "unreadCounts should have 1 entry"; + ASSERT_TRUE((*response.unreadCounts.edges)[0].has_value()) << "edge should be set"; + const auto& unreadCountNode = (*response.unreadCounts.edges)[0]->node; + ASSERT_TRUE(unreadCountNode.has_value()) << "node should be set"; + EXPECT_EQ(today::getFakeFolderId(), unreadCountNode->id) + << "id should match in base64 encoding"; + ASSERT_TRUE(unreadCountNode->name.has_value()) << "name should be set"; + EXPECT_EQ("\"Fake\" Inbox", *(unreadCountNode->name)) << "name should match"; + EXPECT_EQ(3, unreadCountNode->unreadCount) << "unreadCount should match"; + EXPECT_EQ("Folder", unreadCountNode->_typename) << "__typename should match"; + + EXPECT_EQ(query::client::query::Query::TaskState::Unassigned, response.testTaskState) + << "testTaskState should match"; + + ASSERT_EQ(std::size_t { 1 }, response.anyType.size()) << "anyType should have 1 entry"; + ASSERT_TRUE(response.anyType[0].has_value()) << "appointment should be set"; + const auto& anyType = *response.anyType[0]; + EXPECT_EQ("Appointment", anyType._typename) << "__typename should match"; + EXPECT_EQ(today::getFakeAppointmentId(), anyType.id) + << "id should match in base64 encoding"; + EXPECT_FALSE(anyType.title.has_value()) << "appointment should not have a title"; + EXPECT_FALSE(anyType.isComplete) << "appointment should not set isComplete"; + ASSERT_TRUE(anyType.subject.has_value()) << "subject should be set"; + EXPECT_EQ("Lunch?", *(anyType.subject)) << "subject should match"; + ASSERT_TRUE(anyType.when.has_value()) << "when should be set"; + EXPECT_EQ("tomorrow", anyType.when->get()) << "when should match"; + EXPECT_FALSE(anyType.isNow) << "isNow should match"; + } + catch (const std::logic_error& ex) + { + FAIL() << ex.what(); + } +} + TEST_F(ClientCase, MutateCompleteTask) { using namespace mutate::client::mutation::CompleteTaskMutation; From 9664efd40f65e18b92643ccbb3aad80674987ac4 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Thu, 17 Oct 2024 00:02:05 -0700 Subject: [PATCH 093/123] fix: warning on MSVC from switch statements without case --- samples/client/benchmark/TodayClient.cpp | 42 ++++ .../client/multiple/MultipleQueriesClient.cpp | 210 ++++++++++++++++++ samples/client/mutate/MutateClient.cpp | 42 ++++ .../client/nestedinput/NestedInputClient.cpp | 42 ++++ samples/client/query/QueryClient.cpp | 42 ++++ samples/client/subscribe/SubscribeClient.cpp | 42 ++++ samples/proxy/query/ProxyClient.cpp | 42 ++++ src/ClientGenerator.cpp | 42 ++++ 8 files changed, 504 insertions(+) diff --git a/samples/client/benchmark/TodayClient.cpp b/samples/client/benchmark/TodayClient.cpp index 72889197..007b7aad 100644 --- a/samples/client/benchmark/TodayClient.cpp +++ b/samples/client/benchmark/TodayClient.cpp @@ -267,6 +267,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.appointments.edges->back()->node->isNow = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -280,6 +283,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) _pimpl->response.appointments.edges->reserve(count); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -298,6 +304,9 @@ void ResponseVisitor::start_object() _pimpl->response.appointments.edges->back()->node = std::make_optional({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -358,6 +367,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -383,6 +395,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -397,6 +412,9 @@ void ResponseVisitor::start_array() _pimpl->response.appointments.edges = std::make_optional>>({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -410,6 +428,9 @@ void ResponseVisitor::end_array() _pimpl->state = impl::VisitorState::Member_appointments; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -438,6 +459,9 @@ void ResponseVisitor::add_null() _pimpl->response.appointments.edges->back()->node->subject = std::nullopt; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -452,6 +476,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) _pimpl->response.appointments.edges->back()->node->subject = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -463,6 +490,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -477,6 +507,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) _pimpl->response.appointments.edges->back()->node->id = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -496,6 +529,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) _pimpl->response.appointments.edges->back()->node->isNow = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -505,6 +541,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -514,6 +553,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } diff --git a/samples/client/multiple/MultipleQueriesClient.cpp b/samples/client/multiple/MultipleQueriesClient.cpp index 93cdd504..1644ddcb 100644 --- a/samples/client/multiple/MultipleQueriesClient.cpp +++ b/samples/client/multiple/MultipleQueriesClient.cpp @@ -361,6 +361,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.appointments.edges->back()->node->_typename = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -374,6 +377,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) _pimpl->response.appointments.edges->reserve(count); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -392,6 +398,9 @@ void ResponseVisitor::start_object() _pimpl->response.appointments.edges->back()->node = std::make_optional({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -445,6 +454,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -466,6 +478,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -480,6 +495,9 @@ void ResponseVisitor::start_array() _pimpl->response.appointments.edges = std::make_optional>>({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -493,6 +511,9 @@ void ResponseVisitor::end_array() _pimpl->state = impl::VisitorState::Member_appointments; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -521,6 +542,9 @@ void ResponseVisitor::add_null() _pimpl->response.appointments.edges->back()->node->when = std::nullopt; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -540,6 +564,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) _pimpl->response.appointments.edges->back()->node->_typename = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -551,6 +578,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -565,6 +595,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) _pimpl->response.appointments.edges->back()->node->id = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -579,6 +612,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) _pimpl->response.appointments.edges->back()->node->isNow = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -588,6 +624,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -597,6 +636,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -835,6 +877,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.tasks.edges->back()->node->_typename = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -848,6 +893,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) _pimpl->response.tasks.edges->reserve(count); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -866,6 +914,9 @@ void ResponseVisitor::start_object() _pimpl->response.tasks.edges->back()->node = std::make_optional({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -915,6 +966,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -936,6 +990,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -950,6 +1007,9 @@ void ResponseVisitor::start_array() _pimpl->response.tasks.edges = std::make_optional>>({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -963,6 +1023,9 @@ void ResponseVisitor::end_array() _pimpl->state = impl::VisitorState::Member_tasks; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -986,6 +1049,9 @@ void ResponseVisitor::add_null() _pimpl->response.tasks.edges->back()->node->title = std::nullopt; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1005,6 +1071,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) _pimpl->response.tasks.edges->back()->node->_typename = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1016,6 +1085,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -1030,6 +1102,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) _pimpl->response.tasks.edges->back()->node->id = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1044,6 +1119,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) _pimpl->response.tasks.edges->back()->node->isComplete = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1053,6 +1131,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -1062,6 +1143,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -1300,6 +1384,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.unreadCounts.edges->back()->node->_typename = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1313,6 +1400,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) _pimpl->response.unreadCounts.edges->reserve(count); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1331,6 +1421,9 @@ void ResponseVisitor::start_object() _pimpl->response.unreadCounts.edges->back()->node = std::make_optional({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1380,6 +1473,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1401,6 +1497,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1415,6 +1514,9 @@ void ResponseVisitor::start_array() _pimpl->response.unreadCounts.edges = std::make_optional>>({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1428,6 +1530,9 @@ void ResponseVisitor::end_array() _pimpl->state = impl::VisitorState::Member_unreadCounts; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1451,6 +1556,9 @@ void ResponseVisitor::add_null() _pimpl->response.unreadCounts.edges->back()->node->name = std::nullopt; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1470,6 +1578,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) _pimpl->response.unreadCounts.edges->back()->node->_typename = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1481,6 +1592,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -1495,6 +1609,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) _pimpl->response.unreadCounts.edges->back()->node->id = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1504,6 +1621,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -1518,6 +1638,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) _pimpl->response.unreadCounts.edges->back()->node->unreadCount = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1527,6 +1650,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -1782,6 +1908,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.default_ = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1795,6 +1924,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) _pimpl->response.anyType.reserve(count); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1809,6 +1941,9 @@ void ResponseVisitor::start_object() _pimpl->response.anyType.push_back(std::make_optional({})); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1864,6 +1999,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1877,6 +2015,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Member_anyType_0; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1890,6 +2031,9 @@ void ResponseVisitor::start_array() _pimpl->state = impl::VisitorState::Member_anyType_0; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1903,6 +2047,9 @@ void ResponseVisitor::end_array() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1936,6 +2083,9 @@ void ResponseVisitor::add_null() _pimpl->response.default_ = std::nullopt; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1965,6 +2115,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) _pimpl->response.default_ = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1984,6 +2137,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1998,6 +2154,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) _pimpl->response.anyType.back()->id = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -2017,6 +2176,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) _pimpl->response.anyType.back()->isNow = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -2026,6 +2188,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -2035,6 +2200,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -2297,6 +2465,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.completedTask.clientMutationId = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -2306,6 +2477,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -2319,6 +2493,9 @@ void ResponseVisitor::start_object() _pimpl->response.completedTask.completedTask = std::make_optional({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -2361,6 +2538,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -2378,6 +2558,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -2387,6 +2570,9 @@ void ResponseVisitor::start_array() { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -2396,6 +2582,9 @@ void ResponseVisitor::end_array() { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -2420,6 +2609,9 @@ void ResponseVisitor::add_null() _pimpl->response.completedTask.clientMutationId = std::nullopt; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -2439,6 +2631,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) _pimpl->response.completedTask.clientMutationId = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -2450,6 +2645,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -2464,6 +2662,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) _pimpl->response.completedTask.completedTask->completedTaskId = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -2478,6 +2679,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) _pimpl->response.completedTask.completedTask->isComplete = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -2487,6 +2691,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -2496,6 +2703,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } diff --git a/samples/client/mutate/MutateClient.cpp b/samples/client/mutate/MutateClient.cpp index bc32c1d3..f54db298 100644 --- a/samples/client/mutate/MutateClient.cpp +++ b/samples/client/mutate/MutateClient.cpp @@ -324,6 +324,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.completedTask.clientMutationId = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -333,6 +336,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -346,6 +352,9 @@ void ResponseVisitor::start_object() _pimpl->response.completedTask.completedTask = std::make_optional({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -388,6 +397,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -405,6 +417,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -414,6 +429,9 @@ void ResponseVisitor::start_array() { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -423,6 +441,9 @@ void ResponseVisitor::end_array() { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -447,6 +468,9 @@ void ResponseVisitor::add_null() _pimpl->response.completedTask.clientMutationId = std::nullopt; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -466,6 +490,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) _pimpl->response.completedTask.clientMutationId = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -477,6 +504,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -491,6 +521,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) _pimpl->response.completedTask.completedTask->completedTaskId = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -505,6 +538,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) _pimpl->response.completedTask.completedTask->isComplete = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -514,6 +550,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -523,6 +562,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } diff --git a/samples/client/nestedinput/NestedInputClient.cpp b/samples/client/nestedinput/NestedInputClient.cpp index 8e4b4650..549132ac 100644 --- a/samples/client/nestedinput/NestedInputClient.cpp +++ b/samples/client/nestedinput/NestedInputClient.cpp @@ -401,6 +401,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.control.test->id = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -410,6 +413,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -423,6 +429,9 @@ void ResponseVisitor::start_object() _pimpl->response.control.test = std::make_optional({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -453,6 +462,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -470,6 +482,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -479,6 +494,9 @@ void ResponseVisitor::start_array() { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -488,6 +506,9 @@ void ResponseVisitor::end_array() { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -507,6 +528,9 @@ void ResponseVisitor::add_null() _pimpl->response.control.test->id = std::nullopt; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -516,6 +540,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -527,6 +554,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -536,6 +566,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -550,6 +583,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) _pimpl->response.control.test->id = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -559,6 +595,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -568,6 +607,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } diff --git a/samples/client/query/QueryClient.cpp b/samples/client/query/QueryClient.cpp index 072ebec5..e6d9d180 100644 --- a/samples/client/query/QueryClient.cpp +++ b/samples/client/query/QueryClient.cpp @@ -671,6 +671,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.default_ = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -696,6 +699,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) _pimpl->response.anyType.reserve(count); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -737,6 +743,9 @@ void ResponseVisitor::start_object() _pimpl->response.anyType.push_back(std::make_optional({})); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -907,6 +916,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -956,6 +968,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Member_anyType_0; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -984,6 +999,9 @@ void ResponseVisitor::start_array() _pimpl->state = impl::VisitorState::Member_anyType_0; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1009,6 +1027,9 @@ void ResponseVisitor::end_array() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1089,6 +1110,9 @@ void ResponseVisitor::add_null() _pimpl->response.default_ = std::nullopt; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1148,6 +1172,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) _pimpl->response.default_ = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1167,6 +1194,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1196,6 +1226,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) _pimpl->response.anyType.back()->id = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1225,6 +1258,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) _pimpl->response.anyType.back()->isNow = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1239,6 +1275,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) _pimpl->response.unreadCounts.edges->back()->node->unreadCount = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -1248,6 +1287,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } diff --git a/samples/client/subscribe/SubscribeClient.cpp b/samples/client/subscribe/SubscribeClient.cpp index 79fa858d..8ea64274 100644 --- a/samples/client/subscribe/SubscribeClient.cpp +++ b/samples/client/subscribe/SubscribeClient.cpp @@ -164,6 +164,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.nextAppointment->isNow = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -173,6 +176,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -186,6 +192,9 @@ void ResponseVisitor::start_object() _pimpl->response.nextAppointment = std::make_optional({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -221,6 +230,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -234,6 +246,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -243,6 +258,9 @@ void ResponseVisitor::start_array() { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -252,6 +270,9 @@ void ResponseVisitor::end_array() { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -276,6 +297,9 @@ void ResponseVisitor::add_null() _pimpl->response.nextAppointment->subject = std::nullopt; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -290,6 +314,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) _pimpl->response.nextAppointment->subject = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -301,6 +328,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -315,6 +345,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) _pimpl->response.nextAppointment->nextAppointmentId = std::move(value); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -329,6 +362,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) _pimpl->response.nextAppointment->isNow = value; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -338,6 +374,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -347,6 +386,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } diff --git a/samples/proxy/query/ProxyClient.cpp b/samples/proxy/query/ProxyClient.cpp index 7286b49f..8a8362d8 100644 --- a/samples/proxy/query/ProxyClient.cpp +++ b/samples/proxy/query/ProxyClient.cpp @@ -208,6 +208,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.relay.errors->push_back(ModifiedResponse::parse(response::Value { *value })); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -221,6 +224,9 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) _pimpl->response.relay.errors->reserve(count); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -235,6 +241,9 @@ void ResponseVisitor::start_object() _pimpl->response.relay.errors->push_back(std::make_optional({})); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -262,6 +271,9 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) } break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -275,6 +287,9 @@ void ResponseVisitor::end_object() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -289,6 +304,9 @@ void ResponseVisitor::start_array() _pimpl->response.relay.errors = std::make_optional>>({}); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -302,6 +320,9 @@ void ResponseVisitor::end_array() _pimpl->state = impl::VisitorState::Member_relay; break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -320,6 +341,9 @@ void ResponseVisitor::add_null() _pimpl->response.relay.errors->push_back(std::nullopt); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -338,6 +362,9 @@ void ResponseVisitor::add_string([[maybe_unused]] std::string&& value) _pimpl->response.relay.errors->push_back(std::move(value)); break; + case impl::VisitorState::Complete: + break; + default: break; } @@ -349,6 +376,9 @@ void ResponseVisitor::add_enum([[maybe_unused]] std::string&& value) switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -358,6 +388,9 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -367,6 +400,9 @@ void ResponseVisitor::add_bool([[maybe_unused]] bool value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -376,6 +412,9 @@ void ResponseVisitor::add_int([[maybe_unused]] int value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } @@ -385,6 +424,9 @@ void ResponseVisitor::add_float([[maybe_unused]] double value) { switch (_pimpl->state) { + case impl::VisitorState::Complete: + break; + default: break; } diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index feddce14..6f3de4a9 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -1392,6 +1392,9 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptr Date: Fri, 18 Oct 2024 22:14:35 -0700 Subject: [PATCH 094/123] feat: implement Schema merge --- include/graphqlservice/internal/Schema.h | 6 + src/Schema.cpp | 599 +++++++++++++++++++++++ 2 files changed, 605 insertions(+) diff --git a/include/graphqlservice/internal/Schema.h b/include/graphqlservice/internal/Schema.h index 6628a6f5..dce7be83 100644 --- a/include/graphqlservice/internal/Schema.h +++ b/include/graphqlservice/internal/Schema.h @@ -45,6 +45,9 @@ class [[nodiscard("unnecessary construction")]] Schema : public std::enable_shar GRAPHQLSERVICE_EXPORT explicit Schema( bool noIntrospection = false, std::string_view description = ""); + GRAPHQLSERVICE_EXPORT std::shared_ptr StitchSchema( + const std::shared_ptr& added) const; + GRAPHQLSERVICE_EXPORT void AddQueryType(std::shared_ptr query); GRAPHQLSERVICE_EXPORT void AddMutationType(std::shared_ptr mutation); GRAPHQLSERVICE_EXPORT void AddSubscriptionType(std::shared_ptr subscription); @@ -74,6 +77,9 @@ class [[nodiscard("unnecessary construction")]] Schema : public std::enable_shar directives() const noexcept; private: + [[nodiscard("unnecessary call")]] std::shared_ptr StitchFieldType( + std::shared_ptr fieldType); + const bool _noIntrospection = false; const std::string_view _description; diff --git a/src/Schema.cpp b/src/Schema.cpp index b448089a..4f5a9ea4 100644 --- a/src/Schema.cpp +++ b/src/Schema.cpp @@ -17,6 +17,605 @@ Schema::Schema(bool noIntrospection, std::string_view description) { } +std::shared_ptr Schema::StitchSchema(const std::shared_ptr& added) const +{ + const auto noIntrospection = _noIntrospection || added->_noIntrospection; + const auto description = _description.empty() ? added->_description : _description; + auto schema = std::make_shared(noIntrospection, description); + + if (_types.empty()) + { + schema->_query = added->_query; + schema->_mutation = added->_mutation; + schema->_subscription = added->_subscription; + schema->_typeMap = added->_typeMap; + schema->_types = added->_types; + schema->_directives = added->_directives; + } + else if (added->_types.empty()) + { + schema->_query = _query; + schema->_mutation = _mutation; + schema->_subscription = _subscription; + schema->_typeMap = _typeMap; + schema->_types = _types; + schema->_directives = _directives; + } + else + { + internal::string_view_map> objectTypes; + internal::string_view_map> interfaceTypes; + internal::string_view_map> unionTypes; + internal::string_view_map> enumTypes; + internal::string_view_map> inputObjectTypes; + + for (const auto& entry : _types) + { + const auto& [name, originalType] = entry; + + switch (originalType->kind()) + { + case introspection::TypeKind::SCALAR: + { + const auto originalDescription = originalType->description(); + const auto originalSpecifiedByURL = originalType->specifiedByURL(); + const auto itrAdded = added->_typeMap.find(name); + auto scalarType = ScalarType::Make(name, + originalDescription.empty() && itrAdded != added->_typeMap.end() + ? added->_types[itrAdded->second].second->description() + : originalDescription, + originalSpecifiedByURL.empty() && itrAdded != added->_typeMap.end() + ? added->_types[itrAdded->second].second->description() + : originalSpecifiedByURL); + + schema->AddType(name, std::move(scalarType)); + break; + } + + case introspection::TypeKind::OBJECT: + { + const auto originalDescription = originalType->description(); + const auto itrAdded = added->_typeMap.find(name); + auto objectType = ObjectType::Make(name, + originalDescription.empty() && itrAdded != added->_typeMap.end() + ? added->_types[itrAdded->second].second->description() + : originalDescription); + + schema->AddType(name, objectType); + objectTypes[name] = std::move(objectType); + break; + } + + case introspection::TypeKind::INTERFACE: + { + const auto originalDescription = originalType->description(); + const auto itrAdded = added->_typeMap.find(name); + auto interfaceType = InterfaceType::Make(name, + originalDescription.empty() && itrAdded != added->_typeMap.end() + ? added->_types[itrAdded->second].second->description() + : originalDescription); + + schema->AddType(name, interfaceType); + interfaceTypes[name] = std::move(interfaceType); + break; + } + + case introspection::TypeKind::UNION: + { + const auto originalDescription = originalType->description(); + const auto itrAdded = added->_typeMap.find(name); + auto unionType = UnionType::Make(name, + originalDescription.empty() && itrAdded != added->_typeMap.end() + ? added->_types[itrAdded->second].second->description() + : originalDescription); + + schema->AddType(name, unionType); + unionTypes[name] = std::move(unionType); + break; + } + + case introspection::TypeKind::ENUM: + { + const auto originalDescription = originalType->description(); + const auto itrAdded = added->_typeMap.find(name); + auto enumType = EnumType::Make(name, + originalDescription.empty() && itrAdded != added->_typeMap.end() + ? added->_types[itrAdded->second].second->description() + : originalDescription); + + schema->AddType(name, enumType); + enumTypes[name] = std::move(enumType); + break; + } + + case introspection::TypeKind::INPUT_OBJECT: + { + const auto originalDescription = originalType->description(); + const auto itrAdded = added->_typeMap.find(name); + auto inputObjectType = InputObjectType::Make(name, + originalDescription.empty() && itrAdded != added->_typeMap.end() + ? added->_types[itrAdded->second].second->description() + : originalDescription); + + schema->AddType(name, inputObjectType); + inputObjectTypes[name] = std::move(inputObjectType); + break; + } + + case introspection::TypeKind::LIST: + case introspection::TypeKind::NON_NULL: + break; + } + } + + for (const auto& entry : added->_types) + { + const auto& [name, addedType] = entry; + const auto itrOriginal = _typeMap.find(name); + + if (itrOriginal != _typeMap.end()) + { + break; + } + + switch (addedType->kind()) + { + case introspection::TypeKind::SCALAR: + { + auto scalarType = ScalarType::Make(name, + addedType->description(), + addedType->specifiedByURL()); + + schema->AddType(name, std::move(scalarType)); + break; + } + + case introspection::TypeKind::OBJECT: + { + auto objectType = ObjectType::Make(name, addedType->description()); + + schema->AddType(name, objectType); + objectTypes[name] = std::move(objectType); + break; + } + + case introspection::TypeKind::INTERFACE: + { + auto interfaceType = InterfaceType::Make(name, addedType->description()); + + schema->AddType(name, interfaceType); + interfaceTypes[name] = std::move(interfaceType); + break; + } + + case introspection::TypeKind::UNION: + { + auto unionType = UnionType::Make(name, addedType->description()); + + schema->AddType(name, unionType); + unionTypes[name] = std::move(unionType); + break; + } + + case introspection::TypeKind::ENUM: + { + auto enumType = EnumType::Make(name, addedType->description()); + + schema->AddType(name, enumType); + enumTypes[name] = std::move(enumType); + break; + } + + case introspection::TypeKind::INPUT_OBJECT: + { + auto inputObjectType = InputObjectType::Make(name, addedType->description()); + + schema->AddType(name, inputObjectType); + inputObjectTypes[name] = std::move(inputObjectType); + break; + } + + case introspection::TypeKind::LIST: + case introspection::TypeKind::NON_NULL: + break; + } + } + + for (const auto& entry : enumTypes) + { + const auto& [name, stitchedType] = entry; + const auto itrOriginal = _typeMap.find(name); + const auto itrAdded = added->_typeMap.find(name); + internal::string_view_set names; + std::vector stitchedValues; + + if (itrOriginal != _typeMap.end()) + { + const auto& originalType = _types[itrOriginal->second].second; + const auto& enumValues = originalType->enumValues(); + + for (const auto& value : enumValues) + { + names.emplace(value->name()); + stitchedValues.push_back({ + value->name(), + value->description(), + value->deprecationReason(), + }); + } + } + + if (itrAdded != added->_typeMap.end()) + { + const auto& addedType = _types[itrAdded->second].second; + const auto& enumValues = addedType->enumValues(); + + for (const auto& value : enumValues) + { + if (!names.emplace(value->name()).second) + { + continue; + } + + stitchedValues.push_back({ + value->name(), + value->description(), + value->deprecationReason(), + }); + } + } + + stitchedType->AddEnumValues(std::move(stitchedValues)); + } + + for (const auto& entry : inputObjectTypes) + { + const auto& [name, stitchedType] = entry; + const auto itrOriginal = _typeMap.find(name); + const auto itrAdded = added->_typeMap.find(name); + internal::string_view_set names; + std::vector> stitchedValues; + + if (itrOriginal != _typeMap.end()) + { + const auto& originalType = _types[itrOriginal->second].second; + const auto& inputObjectValues = originalType->inputFields(); + + for (const auto& value : inputObjectValues) + { + names.emplace(value->name()); + stitchedValues.push_back(InputValue::Make(value->name(), + value->description(), + schema->StitchFieldType(value->type().lock()), + value->defaultValue())); + } + } + + if (itrAdded != added->_typeMap.end()) + { + const auto& addedType = _types[itrAdded->second].second; + const auto& inputObjectValues = addedType->inputFields(); + + for (const auto& value : inputObjectValues) + { + if (!names.emplace(value->name()).second) + { + continue; + } + + stitchedValues.push_back(InputValue::Make(value->name(), + value->description(), + schema->StitchFieldType(value->type().lock()), + value->defaultValue())); + } + } + + stitchedType->AddInputValues(std::move(stitchedValues)); + } + + for (const auto& entry : interfaceTypes) + { + const auto& [name, stitchedType] = entry; + const auto itrOriginal = _typeMap.find(name); + const auto itrAdded = added->_typeMap.find(name); + internal::string_view_set names; + std::vector> stitchedValues; + + if (itrOriginal != _typeMap.end()) + { + const auto& originalType = _types[itrOriginal->second].second; + const auto& interfaceFields = originalType->fields(); + + for (const auto& field : interfaceFields) + { + std::vector> stitchedArgs; + + for (const auto& value : field->args()) + { + stitchedArgs.push_back(InputValue::Make(value->name(), + value->description(), + schema->StitchFieldType(value->type().lock()), + value->defaultValue())); + } + + names.emplace(field->name()); + stitchedValues.push_back(Field::Make(field->name(), + field->description(), + field->deprecationReason(), + schema->StitchFieldType(field->type().lock()), + std::move(stitchedArgs))); + } + } + + if (itrAdded != added->_typeMap.end()) + { + const auto& addedType = _types[itrAdded->second].second; + const auto& interfaceFields = addedType->fields(); + + for (const auto& field : interfaceFields) + { + if (!names.emplace(field->name()).second) + { + continue; + } + + std::vector> stitchedArgs; + + for (const auto& value : field->args()) + { + stitchedArgs.push_back(InputValue::Make(value->name(), + value->description(), + schema->StitchFieldType(value->type().lock()), + value->defaultValue())); + } + + stitchedValues.push_back(Field::Make(field->name(), + field->description(), + field->deprecationReason(), + schema->StitchFieldType(field->type().lock()), + std::move(stitchedArgs))); + } + } + + stitchedType->AddFields(std::move(stitchedValues)); + } + + for (const auto& entry : unionTypes) + { + const auto& [name, stitchedType] = entry; + const auto itrOriginal = _typeMap.find(name); + const auto itrAdded = added->_typeMap.find(name); + internal::string_view_set names; + std::vector> stitchedValues; + + if (itrOriginal != _typeMap.end()) + { + const auto& originalType = _types[itrOriginal->second].second; + const auto& unionValues = originalType->possibleTypes(); + + for (const auto& value : unionValues) + { + const auto possibleType = value.lock(); + + names.emplace(possibleType->name()); + stitchedValues.push_back(schema->LookupType(possibleType->name())); + } + } + + if (itrAdded != added->_typeMap.end()) + { + const auto& addedType = _types[itrAdded->second].second; + const auto& unionValues = addedType->possibleTypes(); + + for (const auto& value : unionValues) + { + const auto possibleType = value.lock(); + + if (!names.emplace(possibleType->name()).second) + { + continue; + } + + stitchedValues.push_back(schema->LookupType(possibleType->name())); + } + } + + stitchedType->AddPossibleTypes(std::move(stitchedValues)); + } + + for (const auto& entry : objectTypes) + { + const auto& [name, stitchedType] = entry; + const auto itrOriginal = _typeMap.find(name); + const auto itrAdded = added->_typeMap.find(name); + internal::string_view_set interfaceNames; + internal::string_view_set fieldNames; + std::vector> stitchedInterfaces; + std::vector> stitchedValues; + + if (itrOriginal != _typeMap.end()) + { + const auto& originalType = _types[itrOriginal->second].second; + const auto& interfaceValues = originalType->interfaces(); + + for (const auto& value : interfaceValues) + { + interfaceNames.emplace(value->name()); + stitchedInterfaces.push_back(interfaceTypes[value->name()]); + } + + const auto& objectFields = originalType->fields(); + + for (const auto& field : objectFields) + { + std::vector> stitchedArgs; + + for (const auto& value : field->args()) + { + stitchedArgs.push_back(InputValue::Make(value->name(), + value->description(), + schema->StitchFieldType(value->type().lock()), + value->defaultValue())); + } + + fieldNames.emplace(field->name()); + stitchedValues.push_back(Field::Make(field->name(), + field->description(), + field->deprecationReason(), + schema->StitchFieldType(field->type().lock()), + std::move(stitchedArgs))); + } + } + + if (itrAdded != added->_typeMap.end()) + { + const auto& addedType = _types[itrAdded->second].second; + const auto& interfaceValues = addedType->interfaces(); + + for (const auto& value : interfaceValues) + { + if (!interfaceNames.emplace(value->name()).second) + { + continue; + } + + stitchedInterfaces.push_back(interfaceTypes[value->name()]); + } + + const auto& objectFields = addedType->fields(); + + for (const auto& field : objectFields) + { + if (!fieldNames.emplace(field->name()).second) + { + continue; + } + + std::vector> stitchedArgs; + + for (const auto& value : field->args()) + { + stitchedArgs.push_back(InputValue::Make(value->name(), + value->description(), + schema->StitchFieldType(value->type().lock()), + value->defaultValue())); + } + + stitchedValues.push_back(Field::Make(field->name(), + field->description(), + field->deprecationReason(), + schema->StitchFieldType(field->type().lock()), + std::move(stitchedArgs))); + } + } + + stitchedType->AddInterfaces(std::move(stitchedInterfaces)); + stitchedType->AddFields(std::move(stitchedValues)); + } + + internal::string_view_set directiveNames; + std::vector> stitchedDirectives; + + for (const auto& originalDirective : _directives) + { + if (!directiveNames.emplace(originalDirective->name()).second) + { + continue; + } + + std::vector> stitchedArgs; + + for (const auto& value : originalDirective->args()) + { + stitchedArgs.push_back(InputValue::Make(value->name(), + value->description(), + schema->StitchFieldType(value->type().lock()), + value->defaultValue())); + } + + stitchedDirectives.push_back(Directive::Make(originalDirective->name(), + originalDirective->description(), + std::vector { originalDirective->locations() }, + std::move(stitchedArgs), + originalDirective->isRepeatable())); + } + + for (const auto& addedDirective : added->_directives) + { + if (!directiveNames.emplace(addedDirective->name()).second) + { + continue; + } + + std::vector> stitchedArgs; + + for (const auto& value : addedDirective->args()) + { + stitchedArgs.push_back(InputValue::Make(value->name(), + value->description(), + schema->StitchFieldType(value->type().lock()), + value->defaultValue())); + } + + stitchedDirectives.push_back(Directive::Make(addedDirective->name(), + addedDirective->description(), + std::vector { addedDirective->locations() }, + std::move(stitchedArgs), + addedDirective->isRepeatable())); + } + + for (auto& directive : stitchedDirectives) + { + schema->AddDirective(std::move(directive)); + } + + if (_query) + { + schema->AddQueryType(objectTypes[_query->name()]); + } + else if (added->_query) + { + schema->AddQueryType(objectTypes[added->_query->name()]); + } + + if (_mutation) + { + schema->AddMutationType(objectTypes[_mutation->name()]); + } + else if (added->_mutation) + { + schema->AddMutationType(objectTypes[added->_mutation->name()]); + } + + if (_subscription) + { + schema->AddSubscriptionType(objectTypes[_subscription->name()]); + } + else if (added->_subscription) + { + schema->AddSubscriptionType(objectTypes[added->_subscription->name()]); + } + } + + return schema; +} + +std::shared_ptr Schema::StitchFieldType(std::shared_ptr fieldType) +{ + switch (fieldType->kind()) + { + case introspection::TypeKind::LIST: + return WrapType(introspection::TypeKind::LIST, StitchFieldType(std::move(fieldType))); + + case introspection::TypeKind::NON_NULL: + return WrapType(introspection::TypeKind::NON_NULL, + StitchFieldType(std::move(fieldType))); + + default: + return LookupType(fieldType->name()); + } +} + void Schema::AddQueryType(std::shared_ptr query) { _query = query; From b00f34b392e37f01bd95a4d994e004830ad889da Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 19 Oct 2024 17:31:54 -0700 Subject: [PATCH 095/123] chore: code cleanup --- include/graphqlservice/internal/Schema.h | 2 +- src/Schema.cpp | 148 +++++++++++------------ 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/include/graphqlservice/internal/Schema.h b/include/graphqlservice/internal/Schema.h index dce7be83..b38d5303 100644 --- a/include/graphqlservice/internal/Schema.h +++ b/include/graphqlservice/internal/Schema.h @@ -45,7 +45,7 @@ class [[nodiscard("unnecessary construction")]] Schema : public std::enable_shar GRAPHQLSERVICE_EXPORT explicit Schema( bool noIntrospection = false, std::string_view description = ""); - GRAPHQLSERVICE_EXPORT std::shared_ptr StitchSchema( + [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr StitchSchema( const std::shared_ptr& added) const; GRAPHQLSERVICE_EXPORT void AddQueryType(std::shared_ptr query); diff --git a/src/Schema.cpp b/src/Schema.cpp index 4f5a9ea4..a0045527 100644 --- a/src/Schema.cpp +++ b/src/Schema.cpp @@ -319,30 +319,30 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr const auto itrOriginal = _typeMap.find(name); const auto itrAdded = added->_typeMap.find(name); internal::string_view_set names; - std::vector> stitchedValues; + std::vector> stitchedFields; if (itrOriginal != _typeMap.end()) { const auto& originalType = _types[itrOriginal->second].second; const auto& interfaceFields = originalType->fields(); - for (const auto& field : interfaceFields) + for (const auto& interfaceField : interfaceFields) { std::vector> stitchedArgs; - for (const auto& value : field->args()) + for (const auto& arg : interfaceField->args()) { - stitchedArgs.push_back(InputValue::Make(value->name(), - value->description(), - schema->StitchFieldType(value->type().lock()), - value->defaultValue())); + stitchedArgs.push_back(InputValue::Make(arg->name(), + arg->description(), + schema->StitchFieldType(arg->type().lock()), + arg->defaultValue())); } - names.emplace(field->name()); - stitchedValues.push_back(Field::Make(field->name(), - field->description(), - field->deprecationReason(), - schema->StitchFieldType(field->type().lock()), + names.emplace(interfaceField->name()); + stitchedFields.push_back(Field::Make(interfaceField->name(), + interfaceField->description(), + interfaceField->deprecationReason(), + schema->StitchFieldType(interfaceField->type().lock()), std::move(stitchedArgs))); } } @@ -352,32 +352,32 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr const auto& addedType = _types[itrAdded->second].second; const auto& interfaceFields = addedType->fields(); - for (const auto& field : interfaceFields) + for (const auto& interfaceField : interfaceFields) { - if (!names.emplace(field->name()).second) + if (!names.emplace(interfaceField->name()).second) { continue; } std::vector> stitchedArgs; - for (const auto& value : field->args()) + for (const auto& arg : interfaceField->args()) { - stitchedArgs.push_back(InputValue::Make(value->name(), - value->description(), - schema->StitchFieldType(value->type().lock()), - value->defaultValue())); + stitchedArgs.push_back(InputValue::Make(arg->name(), + arg->description(), + schema->StitchFieldType(arg->type().lock()), + arg->defaultValue())); } - stitchedValues.push_back(Field::Make(field->name(), - field->description(), - field->deprecationReason(), - schema->StitchFieldType(field->type().lock()), + stitchedFields.push_back(Field::Make(interfaceField->name(), + interfaceField->description(), + interfaceField->deprecationReason(), + schema->StitchFieldType(interfaceField->type().lock()), std::move(stitchedArgs))); } } - stitchedType->AddFields(std::move(stitchedValues)); + stitchedType->AddFields(std::move(stitchedFields)); } for (const auto& entry : unionTypes) @@ -391,32 +391,32 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr if (itrOriginal != _typeMap.end()) { const auto& originalType = _types[itrOriginal->second].second; - const auto& unionValues = originalType->possibleTypes(); + const auto& possibleTypes = originalType->possibleTypes(); - for (const auto& value : unionValues) + for (const auto& possibleType : possibleTypes) { - const auto possibleType = value.lock(); + const auto possible = possibleType.lock(); - names.emplace(possibleType->name()); - stitchedValues.push_back(schema->LookupType(possibleType->name())); + names.emplace(possible->name()); + stitchedValues.push_back(schema->LookupType(possible->name())); } } if (itrAdded != added->_typeMap.end()) { const auto& addedType = _types[itrAdded->second].second; - const auto& unionValues = addedType->possibleTypes(); + const auto& possibleTypes = addedType->possibleTypes(); - for (const auto& value : unionValues) + for (const auto& possibleType : possibleTypes) { - const auto possibleType = value.lock(); + const auto possible = possibleType.lock(); - if (!names.emplace(possibleType->name()).second) + if (!names.emplace(possible->name()).second) { continue; } - stitchedValues.push_back(schema->LookupType(possibleType->name())); + stitchedValues.push_back(schema->LookupType(possible->name())); } } @@ -436,33 +436,33 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr if (itrOriginal != _typeMap.end()) { const auto& originalType = _types[itrOriginal->second].second; - const auto& interfaceValues = originalType->interfaces(); + const auto& objectInterfaces = originalType->interfaces(); - for (const auto& value : interfaceValues) + for (const auto& interfaceType : objectInterfaces) { - interfaceNames.emplace(value->name()); - stitchedInterfaces.push_back(interfaceTypes[value->name()]); + interfaceNames.emplace(interfaceType->name()); + stitchedInterfaces.push_back(interfaceTypes[interfaceType->name()]); } const auto& objectFields = originalType->fields(); - for (const auto& field : objectFields) + for (const auto& objectField : objectFields) { std::vector> stitchedArgs; - for (const auto& value : field->args()) + for (const auto& arg : objectField->args()) { - stitchedArgs.push_back(InputValue::Make(value->name(), - value->description(), - schema->StitchFieldType(value->type().lock()), - value->defaultValue())); + stitchedArgs.push_back(InputValue::Make(arg->name(), + arg->description(), + schema->StitchFieldType(arg->type().lock()), + arg->defaultValue())); } - fieldNames.emplace(field->name()); - stitchedValues.push_back(Field::Make(field->name(), - field->description(), - field->deprecationReason(), - schema->StitchFieldType(field->type().lock()), + fieldNames.emplace(objectField->name()); + stitchedValues.push_back(Field::Make(objectField->name(), + objectField->description(), + objectField->deprecationReason(), + schema->StitchFieldType(objectField->type().lock()), std::move(stitchedArgs))); } } @@ -470,41 +470,41 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr if (itrAdded != added->_typeMap.end()) { const auto& addedType = _types[itrAdded->second].second; - const auto& interfaceValues = addedType->interfaces(); + const auto& objectInterfaces = addedType->interfaces(); - for (const auto& value : interfaceValues) + for (const auto& interfaceType : objectInterfaces) { - if (!interfaceNames.emplace(value->name()).second) + if (!interfaceNames.emplace(interfaceType->name()).second) { continue; } - stitchedInterfaces.push_back(interfaceTypes[value->name()]); + stitchedInterfaces.push_back(interfaceTypes[interfaceType->name()]); } const auto& objectFields = addedType->fields(); - for (const auto& field : objectFields) + for (const auto& objectField : objectFields) { - if (!fieldNames.emplace(field->name()).second) + if (!fieldNames.emplace(objectField->name()).second) { continue; } std::vector> stitchedArgs; - for (const auto& value : field->args()) + for (const auto& arg : objectField->args()) { - stitchedArgs.push_back(InputValue::Make(value->name(), - value->description(), - schema->StitchFieldType(value->type().lock()), - value->defaultValue())); + stitchedArgs.push_back(InputValue::Make(arg->name(), + arg->description(), + schema->StitchFieldType(arg->type().lock()), + arg->defaultValue())); } - stitchedValues.push_back(Field::Make(field->name(), - field->description(), - field->deprecationReason(), - schema->StitchFieldType(field->type().lock()), + stitchedValues.push_back(Field::Make(objectField->name(), + objectField->description(), + objectField->deprecationReason(), + schema->StitchFieldType(objectField->type().lock()), std::move(stitchedArgs))); } } @@ -525,12 +525,12 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr std::vector> stitchedArgs; - for (const auto& value : originalDirective->args()) + for (const auto& arg : originalDirective->args()) { - stitchedArgs.push_back(InputValue::Make(value->name(), - value->description(), - schema->StitchFieldType(value->type().lock()), - value->defaultValue())); + stitchedArgs.push_back(InputValue::Make(arg->name(), + arg->description(), + schema->StitchFieldType(arg->type().lock()), + arg->defaultValue())); } stitchedDirectives.push_back(Directive::Make(originalDirective->name(), @@ -549,12 +549,12 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr std::vector> stitchedArgs; - for (const auto& value : addedDirective->args()) + for (const auto& arg : addedDirective->args()) { - stitchedArgs.push_back(InputValue::Make(value->name(), - value->description(), - schema->StitchFieldType(value->type().lock()), - value->defaultValue())); + stitchedArgs.push_back(InputValue::Make(arg->name(), + arg->description(), + schema->StitchFieldType(arg->type().lock()), + arg->defaultValue())); } stitchedDirectives.push_back(Directive::Make(addedDirective->name(), From fbbd02a0c51488fa847597b7f026e38eb6aad4f5 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 19 Oct 2024 17:32:50 -0700 Subject: [PATCH 096/123] feat: implement Object resolver and possible types merge --- include/graphqlservice/GraphQLService.h | 5 ++++ src/GraphQLService.cpp | 31 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 95cba892..62550d16 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -824,6 +824,9 @@ class [[nodiscard("unnecessary construction")]] Object : public std::enable_shar GRAPHQLSERVICE_EXPORT explicit Object(TypeNames&& typeNames, ResolverMap&& resolvers) noexcept; GRAPHQLSERVICE_EXPORT virtual ~Object() = default; + [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr StitchObject( + const std::shared_ptr& added) const; + [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT AwaitableResolver resolve( const SelectionSetParams& selectionSetParams, const peg::ast_node& selection, const FragmentMap& fragments, const response::Value& variables) const; @@ -846,6 +849,7 @@ class [[nodiscard("unnecessary construction")]] Object : public std::enable_shar private: TypeNames _typeNames; ResolverMap _resolvers; + std::vector> _stitched; }; // Test if this Type inherits from Object. @@ -1466,6 +1470,7 @@ class [[nodiscard("unnecessary construction")]] Request collectRegistrations(std::string_view field, RequestDeliverFilter&& filter) const noexcept; const TypeMap _operations; + const std::shared_ptr _schema; mutable std::mutex _validationMutex {}; const std::unique_ptr _validation; mutable std::mutex _subscriptionMutex {}; diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index b7df2161..712e5d50 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -1222,6 +1222,37 @@ Object::Object(TypeNames&& typeNames, ResolverMap&& resolvers) noexcept { } +std::shared_ptr Object::StitchObject(const std::shared_ptr& added) const +{ + auto typeNames = _typeNames; + + for (const auto& name : added->_typeNames) + { + typeNames.emplace(name); + } + + auto resolvers = _resolvers; + bool hasStitchedResolvers = false; + + for (const auto& [name, resolver] : added->_resolvers) + { + hasStitchedResolvers = resolvers.emplace(name, resolver).second || hasStitchedResolvers; + } + + std::vector> stitched { shared_from_this() }; + + if (hasStitchedResolvers) + { + stitched.push_back(added); + } + + auto object = std::make_shared(std::move(typeNames), std::move(resolvers)); + + object->_stitched = std::move(stitched); + + return object; +} + AwaitableResolver Object::resolve(const SelectionSetParams& selectionSetParams, const peg::ast_node& selection, const FragmentMap& fragments, const response::Value& variables) const From 62887b0e86845ca64a74280fb3160d1943f439af Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 19 Oct 2024 22:05:48 -0700 Subject: [PATCH 097/123] fix: misc bugs in Schema merge --- src/Schema.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Schema.cpp b/src/Schema.cpp index a0045527..f40f2a38 100644 --- a/src/Schema.cpp +++ b/src/Schema.cpp @@ -155,7 +155,7 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr if (itrOriginal != _typeMap.end()) { - break; + continue; } switch (addedType->kind()) @@ -247,7 +247,7 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr if (itrAdded != added->_typeMap.end()) { - const auto& addedType = _types[itrAdded->second].second; + const auto& addedType = added->_types[itrAdded->second].second; const auto& enumValues = addedType->enumValues(); for (const auto& value : enumValues) @@ -293,7 +293,7 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr if (itrAdded != added->_typeMap.end()) { - const auto& addedType = _types[itrAdded->second].second; + const auto& addedType = added->_types[itrAdded->second].second; const auto& inputObjectValues = addedType->inputFields(); for (const auto& value : inputObjectValues) @@ -349,7 +349,7 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr if (itrAdded != added->_typeMap.end()) { - const auto& addedType = _types[itrAdded->second].second; + const auto& addedType = added->_types[itrAdded->second].second; const auto& interfaceFields = addedType->fields(); for (const auto& interfaceField : interfaceFields) @@ -404,7 +404,7 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr if (itrAdded != added->_typeMap.end()) { - const auto& addedType = _types[itrAdded->second].second; + const auto& addedType = added->_types[itrAdded->second].second; const auto& possibleTypes = addedType->possibleTypes(); for (const auto& possibleType : possibleTypes) @@ -469,7 +469,7 @@ std::shared_ptr Schema::StitchSchema(const std::shared_ptr if (itrAdded != added->_typeMap.end()) { - const auto& addedType = _types[itrAdded->second].second; + const auto& addedType = added->_types[itrAdded->second].second; const auto& objectInterfaces = addedType->interfaces(); for (const auto& interfaceType : objectInterfaces) @@ -605,11 +605,12 @@ std::shared_ptr Schema::StitchFieldType(std::shared_ptrkind()) { case introspection::TypeKind::LIST: - return WrapType(introspection::TypeKind::LIST, StitchFieldType(std::move(fieldType))); + return WrapType(introspection::TypeKind::LIST, + StitchFieldType(fieldType->ofType().lock())); case introspection::TypeKind::NON_NULL: return WrapType(introspection::TypeKind::NON_NULL, - StitchFieldType(std::move(fieldType))); + StitchFieldType(fieldType->ofType().lock())); default: return LookupType(fieldType->name()); From 6d55067849f88a77394aa155738f194beae61ede Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 19 Oct 2024 22:06:54 -0700 Subject: [PATCH 098/123] chore(test): refactor mock services and add a stitched schema sample --- samples/CMakeLists.txt | 5 ++ samples/learn/StarWarsData.cpp | 37 +++++++++--- samples/learn/StarWarsData.h | 4 ++ samples/stitched/CMakeLists.txt | 34 +++++++++++ samples/stitched/StitchedSchema.cpp | 92 +++++++++++++++++++++++++++++ samples/stitched/StitchedSchema.h | 20 +++++++ samples/stitched/sample.cpp | 57 ++++++++++++++++++ samples/today/TodayMock.cpp | 49 ++++++++++----- samples/today/TodayMock.h | 8 ++- samples/today/TodayMock.ixx | 3 + test/ClientTests.cpp | 2 +- test/CoroutineTests.cpp | 2 +- test/NoIntrospectionTests.cpp | 2 +- test/TodayTests.cpp | 2 +- 14 files changed, 289 insertions(+), 28 deletions(-) create mode 100644 samples/stitched/CMakeLists.txt create mode 100644 samples/stitched/StitchedSchema.cpp create mode 100644 samples/stitched/StitchedSchema.h create mode 100644 samples/stitched/sample.cpp diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index c0f54513..b3d479d7 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -9,6 +9,11 @@ endif() add_subdirectory(client) add_subdirectory(learn) + +if(GRAPHQL_BUILD_MODULES) + add_subdirectory(stitched) +endif() + add_subdirectory(validation) if(GRAPHQL_BUILD_HTTP_SAMPLE) diff --git a/samples/learn/StarWarsData.cpp b/samples/learn/StarWarsData.cpp index fcf2397b..7b88178f 100644 --- a/samples/learn/StarWarsData.cpp +++ b/samples/learn/StarWarsData.cpp @@ -14,7 +14,7 @@ using namespace std::literals; namespace graphql::star_wars { -std::shared_ptr GetService() noexcept +std::shared_ptr MakeQuery() noexcept { auto luke = std::make_shared("1000"s, std::make_optional("Luke Skywalker"s), @@ -111,14 +111,35 @@ std::shared_ptr GetService() noexcept { artoo->getId(), artoo }, }; - auto query = - std::make_shared(std::move(heroes), std::move(humans), std::move(droids)); - auto mutation = std::make_shared(); - auto service = std::make_shared(std::move(query), - std::move(mutation), - std::shared_ptr {}); + return std::make_shared( + std::make_shared(std::move(heroes), std::move(humans), std::move(droids))); +} + +std::shared_ptr GetQueryObject() noexcept +{ + return MakeQuery(); +} + +std::shared_ptr MakeMutation() noexcept +{ + return std::make_shared(std::make_shared()); +} + +std::shared_ptr GetMutationObject() noexcept +{ + return MakeMutation(); +} + +std::shared_ptr GetSubscriptionObject() noexcept +{ + return {}; +} - return service; +std::shared_ptr GetService() noexcept +{ + return std::make_shared(MakeQuery(), + MakeMutation(), + std::shared_ptr {}); } } // namespace graphql::star_wars diff --git a/samples/learn/StarWarsData.h b/samples/learn/StarWarsData.h index 1c8e368a..99e38f80 100644 --- a/samples/learn/StarWarsData.h +++ b/samples/learn/StarWarsData.h @@ -10,6 +10,10 @@ namespace graphql::star_wars { +std::shared_ptr GetQueryObject() noexcept; +std::shared_ptr GetMutationObject() noexcept; +std::shared_ptr GetSubscriptionObject() noexcept; + std::shared_ptr GetService() noexcept; } // namespace graphql::star_wars diff --git a/samples/stitched/CMakeLists.txt b/samples/stitched/CMakeLists.txt new file mode 100644 index 00000000..f2396571 --- /dev/null +++ b/samples/stitched/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +cmake_minimum_required(VERSION 3.28) + +add_library(stitchedschema STATIC + StitchedSchema.cpp) +target_link_libraries(stitchedschema PUBLIC star_wars todaygraphql) +target_include_directories(stitchedschema INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +add_executable(stitched sample.cpp) +target_link_libraries(stitched PRIVATE + stitchedschema + graphqljson) + +if(WIN32 AND BUILD_SHARED_LIBS) + add_custom_command(OUTPUT copied_sample_dlls + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + $ + $ + $ + ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E touch copied_sample_dlls + DEPENDS + graphqlservice + graphqljson + graphqlpeg + graphqlresponse) + + add_custom_target(copy_stitched_sample_dlls DEPENDS copied_sample_dlls) + + add_dependencies(stitched copy_stitched_sample_dlls) +endif() diff --git a/samples/stitched/StitchedSchema.cpp b/samples/stitched/StitchedSchema.cpp new file mode 100644 index 00000000..a0f1cc31 --- /dev/null +++ b/samples/stitched/StitchedSchema.cpp @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "StitchedSchema.h" + +#include "StarWarsData.h" +#include "StarWarsSchema.h" + +import GraphQL.Today.Mock; + +namespace graphql::stitched { + +std::shared_ptr GetSchema() +{ + static std::weak_ptr s_wpSchema; + auto schema = s_wpSchema.lock(); + + if (!schema) + { + auto learnSchema = learn::GetSchema(); + auto todaySchema = today::GetSchema(); + schema = learnSchema->StitchSchema(todaySchema); + s_wpSchema = schema; + } + + return schema; +} + +class Operations final : public service::Request +{ +public: + explicit Operations(std::shared_ptr query, + std::shared_ptr mutation, std::shared_ptr subscription); + +private: + std::shared_ptr _query; + std::shared_ptr _mutation; + std::shared_ptr _subscription; +}; + +Operations::Operations(std::shared_ptr query, + std::shared_ptr mutation, std::shared_ptr subscription) + : service::Request( + { + { service::strQuery, query }, + { service::strMutation, mutation }, + { service::strSubscription, subscription }, + }, + GetSchema()) + , _query(std::move(query)) + , _mutation(std::move(mutation)) + , _subscription(std::move(subscription)) +{ +} + +std::shared_ptr GetService() +{ + auto learnQuery = star_wars::GetQueryObject(); + auto todayQuery = std::static_pointer_cast( + std::make_shared(today::mock_query(today::mock_service()))); + auto stitchedQuery = learnQuery->StitchObject(todayQuery); + + auto learnMutation = star_wars::GetMutationObject(); + auto todayMutation = std::static_pointer_cast( + std::make_shared(today::mock_mutation())); + auto stitchedMutation = learnMutation->StitchObject(todayMutation); + + auto learnSubscription = star_wars::GetSubscriptionObject(); + auto todaySubscription = std::static_pointer_cast( + std::make_shared(today::mock_subscription())); + std::shared_ptr stitchedSubscription; + + if (learnSubscription) + { + if (todaySubscription) + { + stitchedSubscription = learnSubscription->StitchObject(todaySubscription); + } + else + { + stitchedSubscription = learnSubscription; + } + } + else + { + stitchedSubscription = todaySubscription; + } + + return std::make_shared(stitchedQuery, stitchedMutation, stitchedSubscription); +} + +} // namespace graphql::stitched diff --git a/samples/stitched/StitchedSchema.h b/samples/stitched/StitchedSchema.h new file mode 100644 index 00000000..682043a1 --- /dev/null +++ b/samples/stitched/StitchedSchema.h @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#ifndef STITCHEDSCHEMA_H +#define STITCHEDSCHEMA_H + +#include "graphqlservice/GraphQLService.h" + +#include "StarWarsSharedTypes.h" +#include "TodaySharedTypes.h" + +namespace graphql::stitched { + +std::shared_ptr GetService(); + +} // namespace graphql::stitched + +#endif // STITCHEDSCHEMA_H diff --git a/samples/stitched/sample.cpp b/samples/stitched/sample.cpp new file mode 100644 index 00000000..ca392726 --- /dev/null +++ b/samples/stitched/sample.cpp @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "StitchedSchema.h" + +#include "graphqlservice/JSONResponse.h" + +#include +#include +#include +#include + +using namespace graphql; + +int main(int argc, char** argv) +{ + auto service = stitched::GetService(); + + std::cout << "Created the service..." << std::endl; + + try + { + peg::ast query; + + if (argc > 1) + { + query = peg::parseFile(argv[1]); + } + else + { + std::istream_iterator start { std::cin >> std::noskipws }, end {}; + std::string input { start, end }; + + query = peg::parseString(std::move(input)); + } + + if (!query.root) + { + std::cerr << "Unknown error!" << std::endl; + std::cerr << std::endl; + return 1; + } + + std::cout << "Executing query..." << std::endl; + + std::cout << response::toJSON( + service->resolve({ query, ((argc > 2) ? argv[2] : "") }).get()) + << std::endl; + } + catch (const std::runtime_error& ex) + { + std::cerr << ex.what() << std::endl; + return 1; + } + + return 0; +} diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index 236b45cf..1d02e4b4 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -62,47 +62,66 @@ const response::IdType& getFakeFolderId() noexcept return s_fakeId; } -std::unique_ptr mock_service() noexcept +std::shared_ptr mock_query(const std::shared_ptr& service) noexcept { - auto result = std::make_unique(); - - auto query = std::make_shared( - [mockService = result.get()]() -> std::vector> { - ++mockService->getAppointmentsCount; + return std::make_shared( + [weakService = std::weak_ptr { service }]() -> std::vector> { + if (auto mockService = weakService.lock()) + { + ++mockService->getAppointmentsCount; + } return { std::make_shared(response::IdType(getFakeAppointmentId()), "tomorrow", "Lunch?", false) }; }, - [mockService = result.get()]() -> std::vector> { - ++mockService->getTasksCount; + [weakService = std::weak_ptr { service }]() -> std::vector> { + if (auto mockService = weakService.lock()) + { + ++mockService->getTasksCount; + } return { std::make_shared(response::IdType(getFakeTaskId()), "Don't forget", true) }; }, - [mockService = result.get()]() -> std::vector> { - ++mockService->getUnreadCountsCount; + [weakService = std::weak_ptr { service }]() -> std::vector> { + if (auto mockService = weakService.lock()) + { + ++mockService->getUnreadCountsCount; + } return { std::make_shared(response::IdType(getFakeFolderId()), "\"Fake\" Inbox", 3) }; }); - auto mutation = std::make_shared( +} + +std::shared_ptr mock_mutation() noexcept +{ + return std::make_shared( [](CompleteTaskInput&& input) -> std::shared_ptr { return std::make_shared( std::make_shared(std::move(input.id), "Mutated Task!", *(input.isComplete)), std::move(input.clientMutationId)); }); - auto subscription = std::make_shared( +} + +std::shared_ptr mock_subscription() noexcept +{ + return std::make_shared( [](const std::shared_ptr&) -> std::shared_ptr { return { std::make_shared(response::IdType(getFakeAppointmentId()), "tomorrow", "Lunch?", true) }; }); +} + +std::shared_ptr mock_service() noexcept +{ + auto result = std::make_shared(); - result->service = std::make_shared(std::move(query), - std::move(mutation), - std::move(subscription)); + result->service = + std::make_shared(mock_query(result), mock_mutation(), mock_subscription()); return result; } diff --git a/samples/today/TodayMock.h b/samples/today/TodayMock.h index 60f97fa1..c057ca2f 100644 --- a/samples/today/TodayMock.h +++ b/samples/today/TodayMock.h @@ -39,7 +39,7 @@ struct TodayMockService std::size_t getUnreadCountsCount {}; }; -std::unique_ptr mock_service() noexcept; +std::shared_ptr mock_service() noexcept; struct RequestState : service::RequestState { @@ -119,6 +119,8 @@ class Query : public std::enable_shared_from_this std::vector> _unreadCounts; }; +std::shared_ptr mock_query(const std::shared_ptr& service) noexcept; + class PageInfo { public: @@ -301,6 +303,8 @@ class Mutation static std::optional _setFloat; }; +std::shared_ptr mock_mutation() noexcept; + class Subscription { public: @@ -332,6 +336,8 @@ class NextAppointmentChange static std::size_t _notifyUnsubscribeCount; }; +std::shared_ptr mock_subscription() noexcept; + class NodeChange { public: diff --git a/samples/today/TodayMock.ixx b/samples/today/TodayMock.ixx index 3bd76425..4b28ab26 100644 --- a/samples/today/TodayMock.ixx +++ b/samples/today/TodayMock.ixx @@ -22,6 +22,7 @@ using today::mock_service; using today::RequestState; using today::Query; +using today::mock_query; using today::PageInfo; using today::Appointment; @@ -34,8 +35,10 @@ using today::FolderEdge; using today::FolderConnection; using today::CompleteTaskPayload; using today::Mutation; +using today::mock_mutation; using today::Subscription; using today::NextAppointmentChange; +using today::mock_subscription; using today::NodeChange; using today::CapturedParams; using today::NestedType; diff --git a/test/ClientTests.cpp b/test/ClientTests.cpp index da28230b..26a1bcb9 100644 --- a/test/ClientTests.cpp +++ b/test/ClientTests.cpp @@ -35,7 +35,7 @@ class ClientCase : public ::testing::Test } protected: - std::unique_ptr _mockService; + std::shared_ptr _mockService; }; TEST_F(ClientCase, QueryEverything) diff --git a/test/CoroutineTests.cpp b/test/CoroutineTests.cpp index 435e0df8..1fb17f78 100644 --- a/test/CoroutineTests.cpp +++ b/test/CoroutineTests.cpp @@ -30,7 +30,7 @@ class CoroutineCase : public ::testing::Test } protected: - std::unique_ptr _mockService; + std::shared_ptr _mockService; }; TEST_F(CoroutineCase, QueryEverythingSync) diff --git a/test/NoIntrospectionTests.cpp b/test/NoIntrospectionTests.cpp index c8779b42..2d2a0c85 100644 --- a/test/NoIntrospectionTests.cpp +++ b/test/NoIntrospectionTests.cpp @@ -34,7 +34,7 @@ class NoIntrospectionServiceCase : public ::testing::Test } protected: - std::unique_ptr _mockService; + std::shared_ptr _mockService; }; TEST_F(NoIntrospectionServiceCase, QueryEverything) diff --git a/test/TodayTests.cpp b/test/TodayTests.cpp index 48699123..fe3e5c6b 100644 --- a/test/TodayTests.cpp +++ b/test/TodayTests.cpp @@ -31,7 +31,7 @@ class TodayServiceCase : public ::testing::Test } protected: - std::unique_ptr _mockService; + std::shared_ptr _mockService; }; TEST_F(TodayServiceCase, QueryEverything) From 8b0102c1fc310950b27a30dbb786c169f7b32610 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 20 Oct 2024 22:08:03 -0700 Subject: [PATCH 099/123] feat: generalize stitched service in Request::stitch --- include/graphqlservice/GraphQLService.h | 3 + samples/learn/StarWarsData.cpp | 15 ----- samples/learn/StarWarsData.h | 4 -- samples/stitched/StitchedSchema.cpp | 78 +------------------------ samples/stitched/StitchedSchema.h | 2 +- samples/today/TodayMock.h | 6 -- samples/today/TodayMock.ixx | 3 - src/GraphQLService.cpp | 77 ++++++++++++++++++++++++ 8 files changed, 83 insertions(+), 105 deletions(-) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 62550d16..a0280fa1 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -1444,6 +1444,9 @@ class [[nodiscard("unnecessary construction")]] Request GRAPHQLSERVICE_EXPORT virtual ~Request(); public: + [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr stitch( + const std::shared_ptr& added) const; + [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::list validate( peg::ast& query) const; diff --git a/samples/learn/StarWarsData.cpp b/samples/learn/StarWarsData.cpp index 7b88178f..d62bb221 100644 --- a/samples/learn/StarWarsData.cpp +++ b/samples/learn/StarWarsData.cpp @@ -115,26 +115,11 @@ std::shared_ptr MakeQuery() noexcept std::make_shared(std::move(heroes), std::move(humans), std::move(droids))); } -std::shared_ptr GetQueryObject() noexcept -{ - return MakeQuery(); -} - std::shared_ptr MakeMutation() noexcept { return std::make_shared(std::make_shared()); } -std::shared_ptr GetMutationObject() noexcept -{ - return MakeMutation(); -} - -std::shared_ptr GetSubscriptionObject() noexcept -{ - return {}; -} - std::shared_ptr GetService() noexcept { return std::make_shared(MakeQuery(), diff --git a/samples/learn/StarWarsData.h b/samples/learn/StarWarsData.h index 99e38f80..1c8e368a 100644 --- a/samples/learn/StarWarsData.h +++ b/samples/learn/StarWarsData.h @@ -10,10 +10,6 @@ namespace graphql::star_wars { -std::shared_ptr GetQueryObject() noexcept; -std::shared_ptr GetMutationObject() noexcept; -std::shared_ptr GetSubscriptionObject() noexcept; - std::shared_ptr GetService() noexcept; } // namespace graphql::star_wars diff --git a/samples/stitched/StitchedSchema.cpp b/samples/stitched/StitchedSchema.cpp index a0f1cc31..1e1dd588 100644 --- a/samples/stitched/StitchedSchema.cpp +++ b/samples/stitched/StitchedSchema.cpp @@ -10,83 +10,9 @@ import GraphQL.Today.Mock; namespace graphql::stitched { -std::shared_ptr GetSchema() +std::shared_ptr GetService() { - static std::weak_ptr s_wpSchema; - auto schema = s_wpSchema.lock(); - - if (!schema) - { - auto learnSchema = learn::GetSchema(); - auto todaySchema = today::GetSchema(); - schema = learnSchema->StitchSchema(todaySchema); - s_wpSchema = schema; - } - - return schema; -} - -class Operations final : public service::Request -{ -public: - explicit Operations(std::shared_ptr query, - std::shared_ptr mutation, std::shared_ptr subscription); - -private: - std::shared_ptr _query; - std::shared_ptr _mutation; - std::shared_ptr _subscription; -}; - -Operations::Operations(std::shared_ptr query, - std::shared_ptr mutation, std::shared_ptr subscription) - : service::Request( - { - { service::strQuery, query }, - { service::strMutation, mutation }, - { service::strSubscription, subscription }, - }, - GetSchema()) - , _query(std::move(query)) - , _mutation(std::move(mutation)) - , _subscription(std::move(subscription)) -{ -} - -std::shared_ptr GetService() -{ - auto learnQuery = star_wars::GetQueryObject(); - auto todayQuery = std::static_pointer_cast( - std::make_shared(today::mock_query(today::mock_service()))); - auto stitchedQuery = learnQuery->StitchObject(todayQuery); - - auto learnMutation = star_wars::GetMutationObject(); - auto todayMutation = std::static_pointer_cast( - std::make_shared(today::mock_mutation())); - auto stitchedMutation = learnMutation->StitchObject(todayMutation); - - auto learnSubscription = star_wars::GetSubscriptionObject(); - auto todaySubscription = std::static_pointer_cast( - std::make_shared(today::mock_subscription())); - std::shared_ptr stitchedSubscription; - - if (learnSubscription) - { - if (todaySubscription) - { - stitchedSubscription = learnSubscription->StitchObject(todaySubscription); - } - else - { - stitchedSubscription = learnSubscription; - } - } - else - { - stitchedSubscription = todaySubscription; - } - - return std::make_shared(stitchedQuery, stitchedMutation, stitchedSubscription); + return star_wars::GetService()->stitch(today::mock_service()->service); } } // namespace graphql::stitched diff --git a/samples/stitched/StitchedSchema.h b/samples/stitched/StitchedSchema.h index 682043a1..4603b05a 100644 --- a/samples/stitched/StitchedSchema.h +++ b/samples/stitched/StitchedSchema.h @@ -13,7 +13,7 @@ namespace graphql::stitched { -std::shared_ptr GetService(); +std::shared_ptr GetService(); } // namespace graphql::stitched diff --git a/samples/today/TodayMock.h b/samples/today/TodayMock.h index c057ca2f..7142dc6e 100644 --- a/samples/today/TodayMock.h +++ b/samples/today/TodayMock.h @@ -119,8 +119,6 @@ class Query : public std::enable_shared_from_this std::vector> _unreadCounts; }; -std::shared_ptr mock_query(const std::shared_ptr& service) noexcept; - class PageInfo { public: @@ -303,8 +301,6 @@ class Mutation static std::optional _setFloat; }; -std::shared_ptr mock_mutation() noexcept; - class Subscription { public: @@ -336,8 +332,6 @@ class NextAppointmentChange static std::size_t _notifyUnsubscribeCount; }; -std::shared_ptr mock_subscription() noexcept; - class NodeChange { public: diff --git a/samples/today/TodayMock.ixx b/samples/today/TodayMock.ixx index 4b28ab26..3bd76425 100644 --- a/samples/today/TodayMock.ixx +++ b/samples/today/TodayMock.ixx @@ -22,7 +22,6 @@ using today::mock_service; using today::RequestState; using today::Query; -using today::mock_query; using today::PageInfo; using today::Appointment; @@ -35,10 +34,8 @@ using today::FolderEdge; using today::FolderConnection; using today::CompleteTaskPayload; using today::Mutation; -using today::mock_mutation; using today::Subscription; using today::NextAppointmentChange; -using today::mock_subscription; using today::NodeChange; using today::CapturedParams; using today::NestedType; diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index 712e5d50..b1ce3a2c 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -1735,6 +1735,7 @@ void SubscriptionDefinitionVisitor::visitInlineFragment(const peg::ast_node& inl Request::Request(TypeMap operationTypes, std::shared_ptr schema) : _operations(std::move(operationTypes)) + , _schema(schema) , _validation(std::make_unique(std::move(schema))) { } @@ -1746,6 +1747,82 @@ Request::~Request() // forward declaration of the class. } +std::shared_ptr Request::stitch(const std::shared_ptr& added) const +{ + TypeMap operations; + auto itrOriginalQuery = _operations.find(strQuery); + auto itrAddedQuery = added->_operations.find(strQuery); + + if (itrOriginalQuery != _operations.end() && itrOriginalQuery->second) + { + if (itrAddedQuery != added->_operations.end() && itrAddedQuery->second) + { + operations.emplace(strQuery, + itrOriginalQuery->second->StitchObject(itrAddedQuery->second)); + } + else + { + operations.emplace(strQuery, itrOriginalQuery->second); + } + } + else if (itrAddedQuery != added->_operations.end() && itrAddedQuery->second) + { + operations.emplace(strQuery, itrAddedQuery->second); + } + + auto itrOriginalMutation = _operations.find(strMutation); + auto itrAddedMutation = added->_operations.find(strMutation); + + if (itrOriginalMutation != _operations.end() && itrOriginalMutation->second) + { + if (itrAddedMutation != added->_operations.end() && itrAddedMutation->second) + { + operations.emplace(strMutation, + itrOriginalMutation->second->StitchObject(itrAddedMutation->second)); + } + else + { + operations.emplace(strMutation, itrOriginalMutation->second); + } + } + else if (itrAddedMutation != added->_operations.end() && itrAddedMutation->second) + { + operations.emplace(strMutation, itrAddedMutation->second); + } + + auto itrOriginalSubscription = _operations.find(strSubscription); + auto itrAddedSubscription = added->_operations.find(strSubscription); + + if (itrOriginalSubscription != _operations.end() && itrOriginalSubscription->second) + { + if (itrAddedSubscription != added->_operations.end() && itrAddedSubscription->second) + { + operations.emplace(strSubscription, + itrOriginalSubscription->second->StitchObject(itrAddedSubscription->second)); + } + else + { + operations.emplace(strSubscription, itrOriginalSubscription->second); + } + } + else if (itrAddedSubscription != added->_operations.end() && itrAddedSubscription->second) + { + operations.emplace(strSubscription, itrAddedSubscription->second); + } + + class StitchedRequest : public Request + { + public: + StitchedRequest(TypeMap operations, std::shared_ptr schema) + : Request { std::move(operations), std::move(schema) } + { + } + }; + + return std::make_shared(std::move(operations), + _schema->StitchSchema(added->_schema)); +} + std::list Request::validate(peg::ast& query) const { std::list errors; From 11d7d0cc73745e4a9f168101a931b5f8fcce23a3 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 21 Oct 2024 18:01:37 -0700 Subject: [PATCH 100/123] feat: add ResolverResult::visit and visitErrorValues --- include/graphqlservice/GraphQLService.h | 4 + include/graphqlservice/Service.ixx | 1 + src/GraphQLService.cpp | 107 +++++++++++++++--------- 3 files changed, 74 insertions(+), 38 deletions(-) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index a0280fa1..1463739e 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -73,6 +73,9 @@ struct [[nodiscard("unnecessary construction")]] schema_error [[nodiscard("unnecessary memory copy")]] GRAPHQLSERVICE_EXPORT response::Value buildErrorValues( std::list&& structuredErrors); +[[nodiscard("unnecessary memory copy")]] GRAPHQLSERVICE_EXPORT response::ValueTokenStream +visitErrorValues(std::list&& structuredErrors); + // This exception bubbles up 1 or more error messages to the JSON results. class [[nodiscard("unnecessary construction")]] schema_exception : public std::exception { @@ -540,6 +543,7 @@ struct [[nodiscard("unnecessary construction")]] ResolverParams : SelectionSetPa struct [[nodiscard("unnecessary construction")]] ResolverResult { [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT response::Value document() &&; + [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT response::ValueTokenStream visit() &&; response::ValueTokenStream data {}; std::list errors {}; diff --git a/include/graphqlservice/Service.ixx b/include/graphqlservice/Service.ixx index 63cc8119..74cf357c 100644 --- a/include/graphqlservice/Service.ixx +++ b/include/graphqlservice/Service.ixx @@ -33,6 +33,7 @@ using service::buildErrorPath; using service::schema_error; using service::buildErrorValues; +using service::visitErrorValues; using service::schema_exception; using service::unimplemented_method; diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index b1ce3a2c..d19961c1 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -17,59 +17,73 @@ using namespace std::literals; namespace graphql::service { -void addErrorMessage(std::string&& message, response::Value& error) +response::ValueTokenStream addErrorMessage(std::string&& message) { - error.emplace_back(std::string { strMessage }, response::Value(std::move(message))); + response::ValueTokenStream result {}; + + result.push_back(response::ValueToken::AddMember { std::string { strMessage } }); + result.push_back(response::ValueToken::StringValue { std::move(message) }); + + return result; } -void addErrorLocation(const schema_location& location, response::Value& error) +response::ValueTokenStream addErrorLocation(const schema_location& location) { + response::ValueTokenStream result {}; + if (location.line == 0) { - return; + return result; } - response::Value errorLocation(response::Type::Map); + result.push_back(response::ValueToken::AddMember { std::string { strLocations } }); - errorLocation.reserve(2); - errorLocation.emplace_back(std::string { strLine }, - response::Value(static_cast(location.line))); - errorLocation.emplace_back(std::string { strColumn }, - response::Value(static_cast(location.column))); + result.push_back(response::ValueToken::StartArray {}); + result.push_back(response::ValueToken::Reserve { 1 }); + result.push_back(response::ValueToken::StartObject {}); + result.push_back(response::ValueToken::Reserve { 2 }); - response::Value errorLocations(response::Type::List); + result.push_back(response::ValueToken::AddMember { std::string { strLine } }); + result.push_back(response::ValueToken::IntValue { static_cast(location.line) }); + result.push_back(response::ValueToken::AddMember { std::string { strColumn } }); + result.push_back(response::ValueToken::IntValue { static_cast(location.column) }); - errorLocations.reserve(1); - errorLocations.emplace_back(std::move(errorLocation)); + result.push_back(response::ValueToken::EndObject {}); + result.push_back(response::ValueToken::EndArray {}); - error.emplace_back(std::string { strLocations }, std::move(errorLocations)); + return result; } -void addErrorPath(const error_path& path, response::Value& error) +response::ValueTokenStream addErrorPath(const error_path& path) { + response::ValueTokenStream result {}; + if (path.empty()) { - return; + return result; } - response::Value errorPath(response::Type::List); + result.push_back(response::ValueToken::AddMember { std::string { strPath } }); + result.push_back(response::ValueToken::StartArray {}); + result.push_back(response::ValueToken::Reserve { path.size() }); - errorPath.reserve(path.size()); for (const auto& segment : path) { if (std::holds_alternative(segment)) { - errorPath.emplace_back( - response::Value { std::string { std::get(segment) } }); + result.push_back(response::ValueToken::StringValue { + std::string { std::get(segment) } }); } else if (std::holds_alternative(segment)) { - errorPath.emplace_back( - response::Value(static_cast(std::get(segment)))); + result.push_back(response::ValueToken::IntValue { + static_cast(std::get(segment)) }); } } - error.emplace_back(std::string { strPath }, std::move(errorPath)); + result.push_back(response::ValueToken::EndArray {}); + + return result; } error_path buildErrorPath(const std::optional& path) @@ -99,22 +113,30 @@ error_path buildErrorPath(const std::optional& path) response::Value buildErrorValues(std::list&& structuredErrors) { - response::Value errors(response::Type::List); + return visitErrorValues(std::move(structuredErrors)).value(); +} + +response::ValueTokenStream visitErrorValues(std::list&& structuredErrors) +{ + response::ValueTokenStream errors; - errors.reserve(structuredErrors.size()); + errors.push_back(response::ValueToken::StartArray {}); + errors.push_back(response::ValueToken::Reserve { structuredErrors.size() }); for (auto& error : structuredErrors) { - response::Value entry(response::Type::Map); + errors.push_back(response::ValueToken::StartObject {}); + errors.push_back(response::ValueToken::Reserve { 3 }); - entry.reserve(3); - addErrorMessage(std::move(error.message), entry); - addErrorLocation(error.location, entry); - addErrorPath(error.path, entry); + errors.append(addErrorMessage(std::move(error.message))); + errors.append(addErrorLocation(error.location)); + errors.append(addErrorPath(error.path)); - errors.emplace_back(std::move(entry)); + errors.push_back(response::ValueToken::EndObject {}); } + errors.push_back(response::ValueToken::EndArray {}); + return errors; } @@ -245,7 +267,7 @@ void await_worker_queue::resumePending() // Default to immediate synchronous execution. await_async::await_async() : _pimpl { std::static_pointer_cast( - std::make_shared>(std::make_shared())) } + std::make_shared>(std::make_shared())) } { } @@ -253,9 +275,9 @@ await_async::await_async() await_async::await_async(std::launch launch) : _pimpl { ((launch & std::launch::async) == std::launch::async) ? std::static_pointer_cast(std::make_shared>( - std::make_shared())) + std::make_shared())) : std::static_pointer_cast(std::make_shared>( - std::make_shared())) } + std::make_shared())) } { } @@ -623,16 +645,25 @@ schema_location ResolverParams::getLocation() const response::Value ResolverResult::document() && { - response::Value document { response::Type::Map }; + return std::move(*this).visit().value(); +} - document.emplace_back(std::string { strData }, std::move(data).value()); +response::ValueTokenStream ResolverResult::visit() && +{ + response::ValueTokenStream result { response::ValueToken::StartObject {} }; + + result.push_back(response::ValueToken::AddMember { std::string { strData } }); + result.append(std::move(data)); if (!errors.empty()) { - document.emplace_back(std::string { strErrors }, buildErrorValues(std::move(errors))); + result.push_back(response::ValueToken::AddMember { std::string { strErrors } }); + result.append(visitErrorValues(std::move(errors))); } - return document; + result.push_back(response::ValueToken::EndObject {}); + + return result; } template <> From 117120bdc730d9345720fa817f94a854245c9705 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Mon, 21 Oct 2024 23:16:59 -0700 Subject: [PATCH 101/123] feat: replace response::Writer with response::ValueVisitor --- doc/json.md | 2 +- include/graphqlservice/GraphQLResponse.h | 100 +------------------- include/graphqlservice/Response.ixx | 2 - src/GraphQLResponse.cpp | 112 +++++++++++++---------- src/RapidJSONResponse.cpp | 46 ++++++++-- src/TaoCppJSONResponse.cpp | 47 ++++++++-- 6 files changed, 141 insertions(+), 168 deletions(-) diff --git a/doc/json.md b/doc/json.md index 4227683a..49cd7827 100644 --- a/doc/json.md +++ b/doc/json.md @@ -58,7 +58,7 @@ private: virtual void end_object() const = 0; virtual void start_array() const = 0; - virtual void end_arrary() const = 0; + virtual void end_array() const = 0; virtual void write_null() const = 0; virtual void write_string(const std::string& value) const = 0; diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index c4bd7765..9a591e33 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -500,7 +500,7 @@ class [[nodiscard("unnecessary construction")]] ValueVisitor final template ValueVisitor(std::shared_ptr writer) noexcept : _concept { std::static_pointer_cast( - std::make_shared>(std::move(writer))) } + std::make_shared>(std::move(writer))) } { } @@ -635,6 +635,8 @@ class [[nodiscard("unnecessary construction")]] ValueTokenStream final ValueTokenStream() noexcept = default; ~ValueTokenStream() = default; + GRAPHQLRESPONSE_EXPORT explicit ValueTokenStream(Value&& value); + ValueTokenStream(ValueTokenStream&&) noexcept = default; ValueTokenStream& operator=(ValueTokenStream&&) noexcept = default; @@ -662,102 +664,6 @@ class [[nodiscard("unnecessary construction")]] ValueTokenStream final std::list _tokens; }; -class [[nodiscard("unnecessary construction")]] Writer final -{ -private: - struct Concept - { - virtual ~Concept() = default; - - virtual void start_object() const = 0; - virtual void add_member(const std::string& key) const = 0; - virtual void end_object() const = 0; - - virtual void start_array() const = 0; - virtual void end_arrary() const = 0; - - virtual void write_null() const = 0; - virtual void write_string(const std::string& value) const = 0; - virtual void write_bool(bool value) const = 0; - virtual void write_int(int value) const = 0; - virtual void write_float(double value) const = 0; - }; - - template - struct Model : Concept - { - explicit Model(std::unique_ptr pimpl) noexcept - : _pimpl { std::move(pimpl) } - { - } - - void start_object() const final - { - _pimpl->start_object(); - } - - void add_member(const std::string& key) const final - { - _pimpl->add_member(key); - } - - void end_object() const final - { - _pimpl->end_object(); - } - - void start_array() const final - { - _pimpl->start_array(); - } - - void end_arrary() const final - { - _pimpl->end_arrary(); - } - - void write_null() const final - { - _pimpl->write_null(); - } - - void write_string(const std::string& value) const final - { - _pimpl->write_string(value); - } - - void write_bool(bool value) const final - { - _pimpl->write_bool(value); - } - - void write_int(int value) const final - { - _pimpl->write_int(value); - } - - void write_float(double value) const final - { - _pimpl->write_float(value); - } - - private: - std::unique_ptr _pimpl; - }; - - const std::shared_ptr _concept; - -public: - template - Writer(std::unique_ptr writer) noexcept - : _concept { std::static_pointer_cast( - std::make_shared>(std::move(writer))) } - { - } - - GRAPHQLRESPONSE_EXPORT void write(Value value) const; -}; - } // namespace graphql::response #endif // GRAPHQLRESPONSE_H diff --git a/include/graphqlservice/Response.ixx b/include/graphqlservice/Response.ixx index 4f83da5d..522a4c6e 100644 --- a/include/graphqlservice/Response.ixx +++ b/include/graphqlservice/Response.ixx @@ -31,8 +31,6 @@ using response::AwaitableValue; using response::ValueVisitor; using response::ValueToken; using response::ValueTokenStream; - -using response::Writer; // clang-format on } // namespace graphql::response diff --git a/src/GraphQLResponse.cpp b/src/GraphQLResponse.cpp index 984a2034..cb829ccb 100644 --- a/src/GraphQLResponse.cpp +++ b/src/GraphQLResponse.cpp @@ -101,9 +101,9 @@ bool IdType::operator==(const IdType& rhs) const noexcept return (std::holds_alternative(_data) ? internal::Base64::compareBase64(std::get(_data), - std::get(rhs._data)) + std::get(rhs._data)) : internal::Base64::compareBase64(std::get(rhs._data), - std::get(_data))) + std::get(_data))) == internal::Base64::Comparison::EqualTo; } @@ -146,7 +146,7 @@ bool IdType::operator<(const IdType& rhs) const noexcept return (std::holds_alternative(_data) ? (internal::Base64::compareBase64(std::get(_data), std::get(rhs._data)) - < internal::Base64::Comparison::EqualTo) + < internal::Base64::Comparison::EqualTo) : (internal::Base64::compareBase64(std::get(rhs._data), std::get(_data))) > internal::Base64::Comparison::EqualTo); @@ -1802,111 +1802,127 @@ void ValueTokenStreamVisitor::add_value(Value&& value) } } -void ValueTokenStream::append(ValueTokenStream&& other) -{ - _tokens.splice(_tokens.end(), std::move(other._tokens)); -} - -void ValueTokenStream::visit(const std::shared_ptr& visitor) && +ValueTokenStream::ValueTokenStream(Value&& value) { - for (auto& token : _tokens) - { - std::move(token).visit(visitor); - } - - visitor->complete(); -} - -Value ValueTokenStream::value() && -{ - auto visitor = std::make_shared(); - - std::move(*this).visit(std::make_shared(visitor)); - - return visitor->value(); -} - -void Writer::write(Value response) const -{ - switch (response.type()) + switch (value.type()) { case Type::Map: { - auto members = response.release(); + auto members = value.release(); - _concept->start_object(); + push_back(ValueToken::StartObject {}); + push_back(ValueToken::Reserve { members.size() }); for (auto& entry : members) { - _concept->add_member(entry.first); - write(std::move(entry.second)); + push_back(ValueToken::AddMember { std::move(entry.first) }); + append(ValueTokenStream { std::move(entry.second) }); } - _concept->end_object(); + push_back(ValueToken::EndObject {}); break; } case Type::List: { - auto elements = response.release(); + auto elements = value.release(); - _concept->start_array(); + push_back(ValueToken::StartArray {}); + push_back(ValueToken::Reserve { elements.size() }); for (auto& entry : elements) { - write(std::move(entry)); + append(ValueTokenStream { std::move(entry) }); } - _concept->end_arrary(); + push_back(ValueToken::EndArray {}); break; } case Type::String: - case Type::EnumValue: - case Type::ID: { - auto value = response.release(); + auto stringValue = value.release(); - _concept->write_string(value); + push_back(ValueToken::StringValue { std::move(stringValue) }); break; } case Type::Null: { - _concept->write_null(); + push_back(ValueToken::NullValue {}); break; } case Type::Boolean: { - _concept->write_bool(response.get()); + push_back(ValueToken::BoolValue { value.get() }); break; } case Type::Int: { - _concept->write_int(response.get()); + push_back(ValueToken::IntValue { value.get() }); break; } case Type::Float: { - _concept->write_float(response.get()); + push_back(ValueToken::FloatValue { value.get() }); + break; + } + + case Type::EnumValue: + { + auto enumValue = value.release(); + + push_back(ValueToken::EnumValue { std::move(enumValue) }); + break; + } + + case Type::ID: + { + auto idValue = value.release(); + + push_back(ValueToken::IdValue { std::move(idValue) }); break; } case Type::Scalar: { - write(response.release()); + append(ValueTokenStream { value.release() }); break; } default: { - _concept->write_null(); + push_back(ValueToken::NullValue {}); break; } } } +void ValueTokenStream::append(ValueTokenStream&& other) +{ + _tokens.splice(_tokens.end(), std::move(other._tokens)); +} + +void ValueTokenStream::visit(const std::shared_ptr& visitor) && +{ + for (auto& token : _tokens) + { + std::move(token).visit(visitor); + } + + visitor->complete(); +} + +Value ValueTokenStream::value() && +{ + auto visitor = std::make_shared(); + + std::move(*this).visit(std::make_shared(visitor)); + + return visitor->value(); +} + } // namespace graphql::response diff --git a/src/RapidJSONResponse.cpp b/src/RapidJSONResponse.cpp index e7067f61..abdcaee4 100644 --- a/src/RapidJSONResponse.cpp +++ b/src/RapidJSONResponse.cpp @@ -16,7 +16,7 @@ namespace graphql::response { -class StreamWriter +class StreamWriter : public std::enable_shared_from_this { public: StreamWriter(rapidjson::StringBuffer& buffer) @@ -24,12 +24,23 @@ class StreamWriter { } + void add_value(std::shared_ptr&& value) + { + auto writer = std::make_shared(shared_from_this()); + + ValueTokenStream(Value { *value }).visit(writer); + } + + void reserve(std::size_t /* count */) + { + } + void start_object() { _writer.StartObject(); } - void add_member(const std::string& key) + void add_member(std::string&& key) { _writer.Key(key.c_str()); } @@ -44,36 +55,50 @@ class StreamWriter _writer.StartArray(); } - void end_arrary() + void end_array() { _writer.EndArray(); } - void write_null() + void add_null() { _writer.Null(); } - void write_string(const std::string& value) + void add_string(std::string&& value) { _writer.String(value.c_str()); } - void write_bool(bool value) + void add_enum(std::string&& value) + { + add_string(std::move(value)); + } + + void add_id(IdType&& value) + { + add_string(value.release()); + } + + void add_bool(bool value) { _writer.Bool(value); } - void write_int(int value) + void add_int(int value) { _writer.Int(value); } - void write_float(double value) + void add_float(double value) { _writer.Double(value); } + void complete() + { + } + private: rapidjson::Writer _writer; }; @@ -81,9 +106,10 @@ class StreamWriter std::string toJSON(Value&& response) { rapidjson::StringBuffer buffer; - Writer writer { std::make_unique(buffer) }; + auto writer = std::make_shared(std::make_shared(buffer)); + + ValueTokenStream(std::move(response)).visit(writer); - writer.write(std::move(response)); return buffer.GetString(); } diff --git a/src/TaoCppJSONResponse.cpp b/src/TaoCppJSONResponse.cpp index 341327b8..3616d621 100644 --- a/src/TaoCppJSONResponse.cpp +++ b/src/TaoCppJSONResponse.cpp @@ -13,7 +13,7 @@ namespace graphql::response { -class StreamWriter +class StreamWriter : public std::enable_shared_from_this { public: StreamWriter(std::ostream& stream) @@ -21,13 +21,24 @@ class StreamWriter { } + void add_value(std::shared_ptr&& value) + { + auto writer = std::make_shared(shared_from_this()); + + ValueTokenStream(Value { *value }).visit(writer); + } + + void reserve(std::size_t /* count */) + { + } + void start_object() { _scopeStack.push_back(Scope::Object); _writer.begin_object(); } - void add_member(const std::string& key) + void add_member(std::string&& key) { _writer.key(key); } @@ -45,43 +56,57 @@ class StreamWriter _writer.begin_array(); } - void end_arrary() + void end_array() { _writer.end_array(); _scopeStack.pop_back(); end_value(); } - void write_null() + void add_null() { _writer.null(); end_value(); } - void write_string(const std::string& value) + void add_string(std::string&& value) { _writer.string(value); end_value(); } - void write_bool(bool value) + void add_enum(std::string&& value) + { + add_string(std::move(value)); + } + + void add_id(IdType&& value) + { + add_string(value.release()); + } + + void add_bool(bool value) { _writer.boolean(value); end_value(); } - void write_int(int value) + void add_int(int value) { _writer.number(static_cast(value)); end_value(); } - void write_float(double value) + void add_float(double value) { _writer.number(value); end_value(); } + void complete() + { + } + private: enum class Scope { @@ -115,8 +140,10 @@ class StreamWriter std::string toJSON(Value&& response) { std::ostringstream stream; - Writer writer { std::make_unique(stream) }; - writer.write(std::move(response)); + auto writer = std::make_shared(std::make_shared(stream)); + + ValueTokenStream(std::move(response)).visit(writer); + return stream.str(); } From 4d7ba4f13631189b733528c3ca79544001f4edeb Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 22 Oct 2024 11:54:30 -0700 Subject: [PATCH 102/123] fix: Object::_stitched can only have 1 or 2 entries --- include/graphqlservice/GraphQLService.h | 3 ++- src/GraphQLService.cpp | 10 ++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 1463739e..0d4f5621 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -13,6 +13,7 @@ #include "internal/DllExports.h" #include "internal/SortedMap.h" +#include #include #include #include @@ -853,7 +854,7 @@ class [[nodiscard("unnecessary construction")]] Object : public std::enable_shar private: TypeNames _typeNames; ResolverMap _resolvers; - std::vector> _stitched; + std::array, 2> _stitched; }; // Test if this Type inherits from Object. diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index d19961c1..59234dcb 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -1270,17 +1270,15 @@ std::shared_ptr Object::StitchObject(const std::shared_ptr hasStitchedResolvers = resolvers.emplace(name, resolver).second || hasStitchedResolvers; } - std::vector> stitched { shared_from_this() }; + auto object = std::make_shared(std::move(typeNames), std::move(resolvers)); + + object->_stitched[0] = shared_from_this(); if (hasStitchedResolvers) { - stitched.push_back(added); + object->_stitched[1] = added; } - auto object = std::make_shared(std::move(typeNames), std::move(resolvers)); - - object->_stitched = std::move(stitched); - return object; } From f605261eb43150453b098a866ffe5468e51cb35d Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 22 Oct 2024 15:52:14 -0700 Subject: [PATCH 103/123] fix: patch introspection resolvers in Object::StitchObject --- include/graphqlservice/GraphQLService.h | 3 +- src/GraphQLService.cpp | 68 +++++++++++++++++++------ 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 0d4f5621..b6c6eac2 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -830,7 +830,8 @@ class [[nodiscard("unnecessary construction")]] Object : public std::enable_shar GRAPHQLSERVICE_EXPORT virtual ~Object() = default; [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr StitchObject( - const std::shared_ptr& added) const; + const std::shared_ptr& added, + const std::shared_ptr& schema = {}) const; [[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT AwaitableResolver resolve( const SelectionSetParams& selectionSetParams, const peg::ast_node& selection, diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index 59234dcb..3cf6b0fa 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -4,6 +4,10 @@ #include "graphqlservice/GraphQLService.h" #include "graphqlservice/internal/Grammar.h" +#include "graphqlservice/internal/Introspection.h" + +#include "graphqlservice/introspection/SchemaObject.h" +#include "graphqlservice/introspection/TypeObject.h" #include "Validation.h" @@ -267,7 +271,7 @@ void await_worker_queue::resumePending() // Default to immediate synchronous execution. await_async::await_async() : _pimpl { std::static_pointer_cast( - std::make_shared>(std::make_shared())) } + std::make_shared>(std::make_shared())) } { } @@ -275,9 +279,9 @@ await_async::await_async() await_async::await_async(std::launch launch) : _pimpl { ((launch & std::launch::async) == std::launch::async) ? std::static_pointer_cast(std::make_shared>( - std::make_shared())) + std::make_shared())) : std::static_pointer_cast(std::make_shared>( - std::make_shared())) } + std::make_shared())) } { } @@ -1253,21 +1257,50 @@ Object::Object(TypeNames&& typeNames, ResolverMap&& resolvers) noexcept { } -std::shared_ptr Object::StitchObject(const std::shared_ptr& added) const +std::shared_ptr Object::StitchObject(const std::shared_ptr& added, + const std::shared_ptr& schema /* = {} */) const { auto typeNames = _typeNames; + auto resolvers = _resolvers; - for (const auto& name : added->_typeNames) + if (schema && schema->supportsIntrospection()) { - typeNames.emplace(name); + resolvers.erase("__schema"sv); + resolvers.emplace("__schema"sv, [schema](ResolverParams&& params) { + return Result::convert( + std::static_pointer_cast(std::make_shared( + std::make_shared(schema))), + std::move(params)); + }); + + resolvers.erase("__type"sv); + resolvers.emplace("__type"sv, [schema](ResolverParams&& params) { + auto argName = ModifiedArgument::require("name", params.arguments); + const auto& baseType = schema->LookupType(argName); + std::shared_ptr result { baseType + ? std::make_shared( + std::make_shared(baseType)) + : nullptr }; + + return ModifiedResult::convert( + result, + std::move(params)); + }); } - auto resolvers = _resolvers; bool hasStitchedResolvers = false; - for (const auto& [name, resolver] : added->_resolvers) + if (added) { - hasStitchedResolvers = resolvers.emplace(name, resolver).second || hasStitchedResolvers; + for (const auto& name : added->_typeNames) + { + typeNames.emplace(name); + } + + for (const auto& [name, resolver] : added->_resolvers) + { + hasStitchedResolvers = resolvers.emplace(name, resolver).second || hasStitchedResolvers; + } } auto object = std::make_shared(std::move(typeNames), std::move(resolvers)); @@ -1779,6 +1812,8 @@ Request::~Request() std::shared_ptr Request::stitch(const std::shared_ptr& added) const { TypeMap operations; + auto schema = _schema->StitchSchema(added->_schema); + std::shared_ptr query; auto itrOriginalQuery = _operations.find(strQuery); auto itrAddedQuery = added->_operations.find(strQuery); @@ -1786,17 +1821,21 @@ std::shared_ptr Request::stitch(const std::shared_ptr_operations.end() && itrAddedQuery->second) { - operations.emplace(strQuery, - itrOriginalQuery->second->StitchObject(itrAddedQuery->second)); + query = itrOriginalQuery->second->StitchObject(itrAddedQuery->second, schema); } else { - operations.emplace(strQuery, itrOriginalQuery->second); + query = itrOriginalQuery->second->StitchObject({}, schema); } } else if (itrAddedQuery != added->_operations.end() && itrAddedQuery->second) { - operations.emplace(strQuery, itrAddedQuery->second); + query = itrAddedQuery->second->StitchObject({}, schema); + } + + if (query) + { + operations.emplace(strQuery, query); } auto itrOriginalMutation = _operations.find(strMutation); @@ -1848,8 +1887,7 @@ std::shared_ptr Request::stitch(const std::shared_ptr(std::move(operations), - _schema->StitchSchema(added->_schema)); + return std::make_shared(std::move(operations), std::move(schema)); } std::list Request::validate(peg::ast& query) const From 7662396290505144aa4ab0eb8954661c29fb8abb Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 22 Oct 2024 16:18:05 -0700 Subject: [PATCH 104/123] fix: code cleanup to reduce duplication --- src/GraphQLService.cpp | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index 3cf6b0fa..abc98739 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -1265,16 +1265,19 @@ std::shared_ptr Object::StitchObject(const std::shared_ptr if (schema && schema->supportsIntrospection()) { - resolvers.erase("__schema"sv); - resolvers.emplace("__schema"sv, [schema](ResolverParams&& params) { + constexpr auto schemaField = R"gql(__schema)gql"sv; + constexpr auto typeField = R"gql(__type)gql"sv; + + resolvers.erase(schemaField); + resolvers.emplace(schemaField, [schema](ResolverParams&& params) { return Result::convert( std::static_pointer_cast(std::make_shared( std::make_shared(schema))), std::move(params)); }); - resolvers.erase("__type"sv); - resolvers.emplace("__type"sv, [schema](ResolverParams&& params) { + resolvers.erase(typeField); + resolvers.emplace(typeField, [schema](ResolverParams&& params) { auto argName = ModifiedArgument::require("name", params.arguments); const auto& baseType = schema->LookupType(argName); std::shared_ptr result { baseType @@ -1813,7 +1816,7 @@ std::shared_ptr Request::stitch(const std::shared_ptrStitchSchema(added->_schema); - std::shared_ptr query; + std::shared_ptr query; auto itrOriginalQuery = _operations.find(strQuery); auto itrAddedQuery = added->_operations.find(strQuery); @@ -1835,9 +1838,10 @@ std::shared_ptr Request::stitch(const std::shared_ptr mutation; auto itrOriginalMutation = _operations.find(strMutation); auto itrAddedMutation = added->_operations.find(strMutation); @@ -1845,19 +1849,24 @@ std::shared_ptr Request::stitch(const std::shared_ptr_operations.end() && itrAddedMutation->second) { - operations.emplace(strMutation, - itrOriginalMutation->second->StitchObject(itrAddedMutation->second)); + mutation = itrOriginalMutation->second->StitchObject(itrAddedMutation->second); } else { - operations.emplace(strMutation, itrOriginalMutation->second); + mutation = itrOriginalMutation->second; } } else if (itrAddedMutation != added->_operations.end() && itrAddedMutation->second) { - operations.emplace(strMutation, itrAddedMutation->second); + mutation = itrAddedMutation->second; + } + + if (mutation) + { + operations.emplace(strMutation, std::move(mutation)); } + std::shared_ptr subscription; auto itrOriginalSubscription = _operations.find(strSubscription); auto itrAddedSubscription = added->_operations.find(strSubscription); @@ -1865,17 +1874,22 @@ std::shared_ptr Request::stitch(const std::shared_ptr_operations.end() && itrAddedSubscription->second) { - operations.emplace(strSubscription, - itrOriginalSubscription->second->StitchObject(itrAddedSubscription->second)); + subscription = + itrOriginalSubscription->second->StitchObject(itrAddedSubscription->second); } else { - operations.emplace(strSubscription, itrOriginalSubscription->second); + subscription = itrOriginalSubscription->second; } } else if (itrAddedSubscription != added->_operations.end() && itrAddedSubscription->second) { - operations.emplace(strSubscription, itrAddedSubscription->second); + subscription = itrAddedSubscription->second; + } + + if (subscription) + { + operations.emplace(strSubscription, std::move(subscription)); } class StitchedRequest : public Request From 634b5132a0b41591be215b8613804a0752f52624 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 22 Oct 2024 18:19:40 -0700 Subject: [PATCH 105/123] fix: only use include directory from taocpp::json --- src/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc8f5b07..7097a31f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -389,9 +389,10 @@ endif() if(GRAPHQL_USE_TAOCPP_JSON) find_package(taocpp-json CONFIG REQUIRED) + get_target_property(TAOCPP_JSON_INCLUDE_DIRS taocpp::json INTERFACE_INCLUDE_DIRECTORIES) set(BUILD_GRAPHQLJSON ON) add_library(graphqljson TaoCppJSONResponse.cpp) - target_link_libraries(graphqljson PRIVATE taocpp::json) + target_include_directories(graphqljson PRIVATE ${TAOCPP_JSON_INCLUDE_DIRS}) elseif(GRAPHQL_USE_RAPIDJSON) find_package(RapidJSON CONFIG REQUIRED) set(BUILD_GRAPHQLJSON ON) From 075e172d6970f587894fdbd2d13a194e0c49f4fc Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Tue, 22 Oct 2024 18:29:50 -0700 Subject: [PATCH 106/123] fix: export internal/DllExports.h --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7097a31f..8a402246 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -88,6 +88,7 @@ target_sources(graphql_internal_modules PUBLIC FILE_SET HEADERS FILES ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.h ${INCLUDE_ROOT}/graphqlservice/internal/Base64.h + ${INCLUDE_ROOT}/graphqlservice/internal/DllExports.h ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.h ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.h ${INCLUDE_ROOT}/graphqlservice/internal/Schema.h From 52afd7fa2eb3967f028bde463f05a77a02975c8e Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 25 Oct 2024 18:58:24 -0700 Subject: [PATCH 107/123] fix: add the file prefix to the include guard macros --- .../graphqlservice/introspection/DirectiveObject.h | 6 +++--- .../graphqlservice/introspection/EnumValueObject.h | 6 +++--- include/graphqlservice/introspection/FieldObject.h | 6 +++--- .../graphqlservice/introspection/InputValueObject.h | 6 +++--- include/graphqlservice/introspection/SchemaObject.h | 6 +++--- include/graphqlservice/introspection/TypeObject.h | 6 +++--- samples/learn/schema/CharacterObject.h | 6 +++--- samples/learn/schema/DroidObject.h | 6 +++--- samples/learn/schema/HumanObject.h | 6 +++--- samples/learn/schema/MutationObject.h | 6 +++--- samples/learn/schema/QueryObject.h | 6 +++--- samples/learn/schema/ReviewObject.h | 6 +++--- samples/learn/schema/SubscriptionObject.h | 6 +++--- samples/proxy/schema/QueryObject.h | 6 +++--- samples/proxy/schema/QueryResultsObject.h | 6 +++--- .../nointrospection/AppointmentConnectionObject.h | 6 +++--- .../today/nointrospection/AppointmentEdgeObject.h | 6 +++--- samples/today/nointrospection/AppointmentObject.h | 6 +++--- .../nointrospection/CompleteTaskPayloadObject.h | 6 +++--- samples/today/nointrospection/ExpensiveObject.h | 6 +++--- .../today/nointrospection/FolderConnectionObject.h | 6 +++--- samples/today/nointrospection/FolderEdgeObject.h | 6 +++--- samples/today/nointrospection/FolderObject.h | 6 +++--- samples/today/nointrospection/MutationObject.h | 6 +++--- samples/today/nointrospection/NestedTypeObject.h | 6 +++--- samples/today/nointrospection/NodeObject.h | 6 +++--- samples/today/nointrospection/PageInfoObject.h | 6 +++--- samples/today/nointrospection/QueryObject.h | 6 +++--- samples/today/nointrospection/SubscriptionObject.h | 6 +++--- samples/today/nointrospection/TaskConnectionObject.h | 6 +++--- samples/today/nointrospection/TaskEdgeObject.h | 6 +++--- samples/today/nointrospection/TaskObject.h | 6 +++--- samples/today/nointrospection/UnionTypeObject.h | 6 +++--- samples/today/schema/AppointmentConnectionObject.h | 6 +++--- samples/today/schema/AppointmentEdgeObject.h | 6 +++--- samples/today/schema/AppointmentObject.h | 6 +++--- samples/today/schema/CompleteTaskPayloadObject.h | 6 +++--- samples/today/schema/ExpensiveObject.h | 6 +++--- samples/today/schema/FolderConnectionObject.h | 6 +++--- samples/today/schema/FolderEdgeObject.h | 6 +++--- samples/today/schema/FolderObject.h | 6 +++--- samples/today/schema/MutationObject.h | 6 +++--- samples/today/schema/NestedTypeObject.h | 6 +++--- samples/today/schema/NodeObject.h | 6 +++--- samples/today/schema/PageInfoObject.h | 6 +++--- samples/today/schema/QueryObject.h | 6 +++--- samples/today/schema/SubscriptionObject.h | 6 +++--- samples/today/schema/TaskConnectionObject.h | 6 +++--- samples/today/schema/TaskEdgeObject.h | 6 +++--- samples/today/schema/TaskObject.h | 6 +++--- samples/today/schema/UnionTypeObject.h | 6 +++--- samples/validation/schema/AlienObject.h | 6 +++--- samples/validation/schema/ArgumentsObject.h | 6 +++--- samples/validation/schema/CatObject.h | 6 +++--- samples/validation/schema/CatOrDogObject.h | 6 +++--- samples/validation/schema/DogObject.h | 6 +++--- samples/validation/schema/DogOrHumanObject.h | 6 +++--- samples/validation/schema/HumanObject.h | 6 +++--- samples/validation/schema/HumanOrAlienObject.h | 6 +++--- samples/validation/schema/MessageObject.h | 6 +++--- samples/validation/schema/MutateDogResultObject.h | 6 +++--- samples/validation/schema/MutationObject.h | 6 +++--- samples/validation/schema/NodeObject.h | 6 +++--- samples/validation/schema/PetObject.h | 6 +++--- samples/validation/schema/QueryObject.h | 6 +++--- samples/validation/schema/ResourceObject.h | 6 +++--- samples/validation/schema/SentientObject.h | 6 +++--- samples/validation/schema/SubscriptionObject.h | 6 +++--- src/SchemaGenerator.cpp | 12 ++++++++---- src/introspection/DirectiveObject.h | 6 +++--- src/introspection/EnumValueObject.h | 6 +++--- src/introspection/FieldObject.h | 6 +++--- src/introspection/InputValueObject.h | 6 +++--- src/introspection/SchemaObject.h | 6 +++--- src/introspection/TypeObject.h | 6 +++--- 75 files changed, 230 insertions(+), 226 deletions(-) diff --git a/include/graphqlservice/introspection/DirectiveObject.h b/include/graphqlservice/introspection/DirectiveObject.h index 20a0620e..f9714caf 100644 --- a/include/graphqlservice/introspection/DirectiveObject.h +++ b/include/graphqlservice/introspection/DirectiveObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef DIRECTIVEOBJECT_H -#define DIRECTIVEOBJECT_H +#ifndef INTROSPECTION_DIRECTIVEOBJECT_H +#define INTROSPECTION_DIRECTIVEOBJECT_H #include "IntrospectionSchema.h" @@ -85,4 +85,4 @@ class [[nodiscard("unnecessary construction")]] Directive final } // namespace graphql::introspection::object -#endif // DIRECTIVEOBJECT_H +#endif // INTROSPECTION_DIRECTIVEOBJECT_H diff --git a/include/graphqlservice/introspection/EnumValueObject.h b/include/graphqlservice/introspection/EnumValueObject.h index 0ac9e74f..a97c9534 100644 --- a/include/graphqlservice/introspection/EnumValueObject.h +++ b/include/graphqlservice/introspection/EnumValueObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef ENUMVALUEOBJECT_H -#define ENUMVALUEOBJECT_H +#ifndef INTROSPECTION_ENUMVALUEOBJECT_H +#define INTROSPECTION_ENUMVALUEOBJECT_H #include "IntrospectionSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] EnumValue final } // namespace graphql::introspection::object -#endif // ENUMVALUEOBJECT_H +#endif // INTROSPECTION_ENUMVALUEOBJECT_H diff --git a/include/graphqlservice/introspection/FieldObject.h b/include/graphqlservice/introspection/FieldObject.h index f835c5ae..07fba6ae 100644 --- a/include/graphqlservice/introspection/FieldObject.h +++ b/include/graphqlservice/introspection/FieldObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef FIELDOBJECT_H -#define FIELDOBJECT_H +#ifndef INTROSPECTION_FIELDOBJECT_H +#define INTROSPECTION_FIELDOBJECT_H #include "IntrospectionSchema.h" @@ -92,4 +92,4 @@ class [[nodiscard("unnecessary construction")]] Field final } // namespace graphql::introspection::object -#endif // FIELDOBJECT_H +#endif // INTROSPECTION_FIELDOBJECT_H diff --git a/include/graphqlservice/introspection/InputValueObject.h b/include/graphqlservice/introspection/InputValueObject.h index 70faa321..8dda3e79 100644 --- a/include/graphqlservice/introspection/InputValueObject.h +++ b/include/graphqlservice/introspection/InputValueObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef INPUTVALUEOBJECT_H -#define INPUTVALUEOBJECT_H +#ifndef INTROSPECTION_INPUTVALUEOBJECT_H +#define INTROSPECTION_INPUTVALUEOBJECT_H #include "IntrospectionSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] InputValue final } // namespace graphql::introspection::object -#endif // INPUTVALUEOBJECT_H +#endif // INTROSPECTION_INPUTVALUEOBJECT_H diff --git a/include/graphqlservice/introspection/SchemaObject.h b/include/graphqlservice/introspection/SchemaObject.h index fd3659c1..53b12b69 100644 --- a/include/graphqlservice/introspection/SchemaObject.h +++ b/include/graphqlservice/introspection/SchemaObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef SCHEMAOBJECT_H -#define SCHEMAOBJECT_H +#ifndef INTROSPECTION_SCHEMAOBJECT_H +#define INTROSPECTION_SCHEMAOBJECT_H #include "IntrospectionSchema.h" @@ -92,4 +92,4 @@ class [[nodiscard("unnecessary construction")]] Schema final } // namespace graphql::introspection::object -#endif // SCHEMAOBJECT_H +#endif // INTROSPECTION_SCHEMAOBJECT_H diff --git a/include/graphqlservice/introspection/TypeObject.h b/include/graphqlservice/introspection/TypeObject.h index 3b350e1c..993e6dd7 100644 --- a/include/graphqlservice/introspection/TypeObject.h +++ b/include/graphqlservice/introspection/TypeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TYPEOBJECT_H -#define TYPEOBJECT_H +#ifndef INTROSPECTION_TYPEOBJECT_H +#define INTROSPECTION_TYPEOBJECT_H #include "IntrospectionSchema.h" @@ -120,4 +120,4 @@ class [[nodiscard("unnecessary construction")]] Type final } // namespace graphql::introspection::object -#endif // TYPEOBJECT_H +#endif // INTROSPECTION_TYPEOBJECT_H diff --git a/samples/learn/schema/CharacterObject.h b/samples/learn/schema/CharacterObject.h index fbdf2925..213ab726 100644 --- a/samples/learn/schema/CharacterObject.h +++ b/samples/learn/schema/CharacterObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef CHARACTEROBJECT_H -#define CHARACTEROBJECT_H +#ifndef STARWARS_CHARACTEROBJECT_H +#define STARWARS_CHARACTEROBJECT_H #include "StarWarsSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] Character final } // namespace graphql::learn::object -#endif // CHARACTEROBJECT_H +#endif // STARWARS_CHARACTEROBJECT_H diff --git a/samples/learn/schema/DroidObject.h b/samples/learn/schema/DroidObject.h index 0722561d..540cf17e 100644 --- a/samples/learn/schema/DroidObject.h +++ b/samples/learn/schema/DroidObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef DROIDOBJECT_H -#define DROIDOBJECT_H +#ifndef STARWARS_DROIDOBJECT_H +#define STARWARS_DROIDOBJECT_H #include "StarWarsSchema.h" @@ -248,4 +248,4 @@ class [[nodiscard("unnecessary construction")]] Droid final } // namespace graphql::learn::object -#endif // DROIDOBJECT_H +#endif // STARWARS_DROIDOBJECT_H diff --git a/samples/learn/schema/HumanObject.h b/samples/learn/schema/HumanObject.h index 836006ab..f3fede8d 100644 --- a/samples/learn/schema/HumanObject.h +++ b/samples/learn/schema/HumanObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef HUMANOBJECT_H -#define HUMANOBJECT_H +#ifndef STARWARS_HUMANOBJECT_H +#define STARWARS_HUMANOBJECT_H #include "StarWarsSchema.h" @@ -248,4 +248,4 @@ class [[nodiscard("unnecessary construction")]] Human final } // namespace graphql::learn::object -#endif // HUMANOBJECT_H +#endif // STARWARS_HUMANOBJECT_H diff --git a/samples/learn/schema/MutationObject.h b/samples/learn/schema/MutationObject.h index 004e4dcc..8b5efc89 100644 --- a/samples/learn/schema/MutationObject.h +++ b/samples/learn/schema/MutationObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef MUTATIONOBJECT_H -#define MUTATIONOBJECT_H +#ifndef STARWARS_MUTATIONOBJECT_H +#define STARWARS_MUTATIONOBJECT_H #include "StarWarsSchema.h" @@ -124,4 +124,4 @@ class [[nodiscard("unnecessary construction")]] Mutation final } // namespace graphql::learn::object -#endif // MUTATIONOBJECT_H +#endif // STARWARS_MUTATIONOBJECT_H diff --git a/samples/learn/schema/QueryObject.h b/samples/learn/schema/QueryObject.h index a1bace97..ca68c38f 100644 --- a/samples/learn/schema/QueryObject.h +++ b/samples/learn/schema/QueryObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef QUERYOBJECT_H -#define QUERYOBJECT_H +#ifndef STARWARS_QUERYOBJECT_H +#define STARWARS_QUERYOBJECT_H #include "StarWarsSchema.h" @@ -182,4 +182,4 @@ class [[nodiscard("unnecessary construction")]] Query final } // namespace graphql::learn::object -#endif // QUERYOBJECT_H +#endif // STARWARS_QUERYOBJECT_H diff --git a/samples/learn/schema/ReviewObject.h b/samples/learn/schema/ReviewObject.h index 69220738..991bcc15 100644 --- a/samples/learn/schema/ReviewObject.h +++ b/samples/learn/schema/ReviewObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef REVIEWOBJECT_H -#define REVIEWOBJECT_H +#ifndef STARWARS_REVIEWOBJECT_H +#define STARWARS_REVIEWOBJECT_H #include "StarWarsSchema.h" @@ -151,4 +151,4 @@ class [[nodiscard("unnecessary construction")]] Review final } // namespace graphql::learn::object -#endif // REVIEWOBJECT_H +#endif // STARWARS_REVIEWOBJECT_H diff --git a/samples/learn/schema/SubscriptionObject.h b/samples/learn/schema/SubscriptionObject.h index 958211fa..93613e3e 100644 --- a/samples/learn/schema/SubscriptionObject.h +++ b/samples/learn/schema/SubscriptionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef SUBSCRIPTIONOBJECT_H -#define SUBSCRIPTIONOBJECT_H +#ifndef STARWARS_SUBSCRIPTIONOBJECT_H +#define STARWARS_SUBSCRIPTIONOBJECT_H #include "StarWarsSchema.h" @@ -161,4 +161,4 @@ class [[nodiscard("unnecessary construction")]] Subscription final } // namespace graphql::learn::object -#endif // SUBSCRIPTIONOBJECT_H +#endif // STARWARS_SUBSCRIPTIONOBJECT_H diff --git a/samples/proxy/schema/QueryObject.h b/samples/proxy/schema/QueryObject.h index ed350a05..c93e5f75 100644 --- a/samples/proxy/schema/QueryObject.h +++ b/samples/proxy/schema/QueryObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef QUERYOBJECT_H -#define QUERYOBJECT_H +#ifndef PROXY_QUERYOBJECT_H +#define PROXY_QUERYOBJECT_H #include "ProxySchema.h" @@ -128,4 +128,4 @@ class [[nodiscard("unnecessary construction")]] Query final } // namespace graphql::proxy::object -#endif // QUERYOBJECT_H +#endif // PROXY_QUERYOBJECT_H diff --git a/samples/proxy/schema/QueryResultsObject.h b/samples/proxy/schema/QueryResultsObject.h index bd4ef01e..2649a572 100644 --- a/samples/proxy/schema/QueryResultsObject.h +++ b/samples/proxy/schema/QueryResultsObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef QUERYRESULTSOBJECT_H -#define QUERYRESULTSOBJECT_H +#ifndef PROXY_QUERYRESULTSOBJECT_H +#define PROXY_QUERYRESULTSOBJECT_H #include "ProxySchema.h" @@ -151,4 +151,4 @@ class [[nodiscard("unnecessary construction")]] QueryResults final } // namespace graphql::proxy::object -#endif // QUERYRESULTSOBJECT_H +#endif // PROXY_QUERYRESULTSOBJECT_H diff --git a/samples/today/nointrospection/AppointmentConnectionObject.h b/samples/today/nointrospection/AppointmentConnectionObject.h index cfca668b..07f856fc 100644 --- a/samples/today/nointrospection/AppointmentConnectionObject.h +++ b/samples/today/nointrospection/AppointmentConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef APPOINTMENTCONNECTIONOBJECT_H -#define APPOINTMENTCONNECTIONOBJECT_H +#ifndef TODAY_APPOINTMENTCONNECTIONOBJECT_H +#define TODAY_APPOINTMENTCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] AppointmentConnection final } // namespace graphql::today::object -#endif // APPOINTMENTCONNECTIONOBJECT_H +#endif // TODAY_APPOINTMENTCONNECTIONOBJECT_H diff --git a/samples/today/nointrospection/AppointmentEdgeObject.h b/samples/today/nointrospection/AppointmentEdgeObject.h index d8c71b48..5f5d3c7c 100644 --- a/samples/today/nointrospection/AppointmentEdgeObject.h +++ b/samples/today/nointrospection/AppointmentEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef APPOINTMENTEDGEOBJECT_H -#define APPOINTMENTEDGEOBJECT_H +#ifndef TODAY_APPOINTMENTEDGEOBJECT_H +#define TODAY_APPOINTMENTEDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] AppointmentEdge final } // namespace graphql::today::object -#endif // APPOINTMENTEDGEOBJECT_H +#endif // TODAY_APPOINTMENTEDGEOBJECT_H diff --git a/samples/today/nointrospection/AppointmentObject.h b/samples/today/nointrospection/AppointmentObject.h index 0267f113..736e7a60 100644 --- a/samples/today/nointrospection/AppointmentObject.h +++ b/samples/today/nointrospection/AppointmentObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef APPOINTMENTOBJECT_H -#define APPOINTMENTOBJECT_H +#ifndef TODAY_APPOINTMENTOBJECT_H +#define TODAY_APPOINTMENTOBJECT_H #include "TodaySchema.h" @@ -266,4 +266,4 @@ class [[nodiscard("unnecessary construction")]] Appointment final } // namespace graphql::today::object -#endif // APPOINTMENTOBJECT_H +#endif // TODAY_APPOINTMENTOBJECT_H diff --git a/samples/today/nointrospection/CompleteTaskPayloadObject.h b/samples/today/nointrospection/CompleteTaskPayloadObject.h index ccac3881..bd85d417 100644 --- a/samples/today/nointrospection/CompleteTaskPayloadObject.h +++ b/samples/today/nointrospection/CompleteTaskPayloadObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef COMPLETETASKPAYLOADOBJECT_H -#define COMPLETETASKPAYLOADOBJECT_H +#ifndef TODAY_COMPLETETASKPAYLOADOBJECT_H +#define TODAY_COMPLETETASKPAYLOADOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] CompleteTaskPayload final } // namespace graphql::today::object -#endif // COMPLETETASKPAYLOADOBJECT_H +#endif // TODAY_COMPLETETASKPAYLOADOBJECT_H diff --git a/samples/today/nointrospection/ExpensiveObject.h b/samples/today/nointrospection/ExpensiveObject.h index bea1cd2c..2ad7e18f 100644 --- a/samples/today/nointrospection/ExpensiveObject.h +++ b/samples/today/nointrospection/ExpensiveObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef EXPENSIVEOBJECT_H -#define EXPENSIVEOBJECT_H +#ifndef TODAY_EXPENSIVEOBJECT_H +#define TODAY_EXPENSIVEOBJECT_H #include "TodaySchema.h" @@ -127,4 +127,4 @@ class [[nodiscard("unnecessary construction")]] Expensive final } // namespace graphql::today::object -#endif // EXPENSIVEOBJECT_H +#endif // TODAY_EXPENSIVEOBJECT_H diff --git a/samples/today/nointrospection/FolderConnectionObject.h b/samples/today/nointrospection/FolderConnectionObject.h index 61e6729f..92a5882a 100644 --- a/samples/today/nointrospection/FolderConnectionObject.h +++ b/samples/today/nointrospection/FolderConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef FOLDERCONNECTIONOBJECT_H -#define FOLDERCONNECTIONOBJECT_H +#ifndef TODAY_FOLDERCONNECTIONOBJECT_H +#define TODAY_FOLDERCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] FolderConnection final } // namespace graphql::today::object -#endif // FOLDERCONNECTIONOBJECT_H +#endif // TODAY_FOLDERCONNECTIONOBJECT_H diff --git a/samples/today/nointrospection/FolderEdgeObject.h b/samples/today/nointrospection/FolderEdgeObject.h index dc7a0d28..b132f8c1 100644 --- a/samples/today/nointrospection/FolderEdgeObject.h +++ b/samples/today/nointrospection/FolderEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef FOLDEREDGEOBJECT_H -#define FOLDEREDGEOBJECT_H +#ifndef TODAY_FOLDEREDGEOBJECT_H +#define TODAY_FOLDEREDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] FolderEdge final } // namespace graphql::today::object -#endif // FOLDEREDGEOBJECT_H +#endif // TODAY_FOLDEREDGEOBJECT_H diff --git a/samples/today/nointrospection/FolderObject.h b/samples/today/nointrospection/FolderObject.h index 2376bc55..69312e75 100644 --- a/samples/today/nointrospection/FolderObject.h +++ b/samples/today/nointrospection/FolderObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef FOLDEROBJECT_H -#define FOLDEROBJECT_H +#ifndef TODAY_FOLDEROBJECT_H +#define TODAY_FOLDEROBJECT_H #include "TodaySchema.h" @@ -206,4 +206,4 @@ class [[nodiscard("unnecessary construction")]] Folder final } // namespace graphql::today::object -#endif // FOLDEROBJECT_H +#endif // TODAY_FOLDEROBJECT_H diff --git a/samples/today/nointrospection/MutationObject.h b/samples/today/nointrospection/MutationObject.h index 0da072bc..b751f79b 100644 --- a/samples/today/nointrospection/MutationObject.h +++ b/samples/today/nointrospection/MutationObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef MUTATIONOBJECT_H -#define MUTATIONOBJECT_H +#ifndef TODAY_MUTATIONOBJECT_H +#define TODAY_MUTATIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] Mutation final } // namespace graphql::today::object -#endif // MUTATIONOBJECT_H +#endif // TODAY_MUTATIONOBJECT_H diff --git a/samples/today/nointrospection/NestedTypeObject.h b/samples/today/nointrospection/NestedTypeObject.h index 539f72db..e0d88c9b 100644 --- a/samples/today/nointrospection/NestedTypeObject.h +++ b/samples/today/nointrospection/NestedTypeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef NESTEDTYPEOBJECT_H -#define NESTEDTYPEOBJECT_H +#ifndef TODAY_NESTEDTYPEOBJECT_H +#define TODAY_NESTEDTYPEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] NestedType final } // namespace graphql::today::object -#endif // NESTEDTYPEOBJECT_H +#endif // TODAY_NESTEDTYPEOBJECT_H diff --git a/samples/today/nointrospection/NodeObject.h b/samples/today/nointrospection/NodeObject.h index 0310cdba..85f82969 100644 --- a/samples/today/nointrospection/NodeObject.h +++ b/samples/today/nointrospection/NodeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef NODEOBJECT_H -#define NODEOBJECT_H +#ifndef TODAY_NODEOBJECT_H +#define TODAY_NODEOBJECT_H #include "TodaySchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] Node final } // namespace graphql::today::object -#endif // NODEOBJECT_H +#endif // TODAY_NODEOBJECT_H diff --git a/samples/today/nointrospection/PageInfoObject.h b/samples/today/nointrospection/PageInfoObject.h index f4f10741..4b33b8ca 100644 --- a/samples/today/nointrospection/PageInfoObject.h +++ b/samples/today/nointrospection/PageInfoObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef PAGEINFOOBJECT_H -#define PAGEINFOOBJECT_H +#ifndef TODAY_PAGEINFOOBJECT_H +#define TODAY_PAGEINFOOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] PageInfo final } // namespace graphql::today::object -#endif // PAGEINFOOBJECT_H +#endif // TODAY_PAGEINFOOBJECT_H diff --git a/samples/today/nointrospection/QueryObject.h b/samples/today/nointrospection/QueryObject.h index 5ecf2358..ed836819 100644 --- a/samples/today/nointrospection/QueryObject.h +++ b/samples/today/nointrospection/QueryObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef QUERYOBJECT_H -#define QUERYOBJECT_H +#ifndef TODAY_QUERYOBJECT_H +#define TODAY_QUERYOBJECT_H #include "TodaySchema.h" @@ -487,4 +487,4 @@ class [[nodiscard("unnecessary construction")]] Query final } // namespace graphql::today::object -#endif // QUERYOBJECT_H +#endif // TODAY_QUERYOBJECT_H diff --git a/samples/today/nointrospection/SubscriptionObject.h b/samples/today/nointrospection/SubscriptionObject.h index c9179d85..c5bef36d 100644 --- a/samples/today/nointrospection/SubscriptionObject.h +++ b/samples/today/nointrospection/SubscriptionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef SUBSCRIPTIONOBJECT_H -#define SUBSCRIPTIONOBJECT_H +#ifndef TODAY_SUBSCRIPTIONOBJECT_H +#define TODAY_SUBSCRIPTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] Subscription final } // namespace graphql::today::object -#endif // SUBSCRIPTIONOBJECT_H +#endif // TODAY_SUBSCRIPTIONOBJECT_H diff --git a/samples/today/nointrospection/TaskConnectionObject.h b/samples/today/nointrospection/TaskConnectionObject.h index c82b2ae7..2ee84568 100644 --- a/samples/today/nointrospection/TaskConnectionObject.h +++ b/samples/today/nointrospection/TaskConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TASKCONNECTIONOBJECT_H -#define TASKCONNECTIONOBJECT_H +#ifndef TODAY_TASKCONNECTIONOBJECT_H +#define TODAY_TASKCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] TaskConnection final } // namespace graphql::today::object -#endif // TASKCONNECTIONOBJECT_H +#endif // TODAY_TASKCONNECTIONOBJECT_H diff --git a/samples/today/nointrospection/TaskEdgeObject.h b/samples/today/nointrospection/TaskEdgeObject.h index 4049d5c3..5d57eadf 100644 --- a/samples/today/nointrospection/TaskEdgeObject.h +++ b/samples/today/nointrospection/TaskEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TASKEDGEOBJECT_H -#define TASKEDGEOBJECT_H +#ifndef TODAY_TASKEDGEOBJECT_H +#define TODAY_TASKEDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] TaskEdge final } // namespace graphql::today::object -#endif // TASKEDGEOBJECT_H +#endif // TODAY_TASKEDGEOBJECT_H diff --git a/samples/today/nointrospection/TaskObject.h b/samples/today/nointrospection/TaskObject.h index 36548d0b..6214d27a 100644 --- a/samples/today/nointrospection/TaskObject.h +++ b/samples/today/nointrospection/TaskObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TASKOBJECT_H -#define TASKOBJECT_H +#ifndef TODAY_TASKOBJECT_H +#define TODAY_TASKOBJECT_H #include "TodaySchema.h" @@ -206,4 +206,4 @@ class [[nodiscard("unnecessary construction")]] Task final } // namespace graphql::today::object -#endif // TASKOBJECT_H +#endif // TODAY_TASKOBJECT_H diff --git a/samples/today/nointrospection/UnionTypeObject.h b/samples/today/nointrospection/UnionTypeObject.h index 1be8494e..0ee56b2b 100644 --- a/samples/today/nointrospection/UnionTypeObject.h +++ b/samples/today/nointrospection/UnionTypeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef UNIONTYPEOBJECT_H -#define UNIONTYPEOBJECT_H +#ifndef TODAY_UNIONTYPEOBJECT_H +#define TODAY_UNIONTYPEOBJECT_H #include "TodaySchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] UnionType final } // namespace graphql::today::object -#endif // UNIONTYPEOBJECT_H +#endif // TODAY_UNIONTYPEOBJECT_H diff --git a/samples/today/schema/AppointmentConnectionObject.h b/samples/today/schema/AppointmentConnectionObject.h index cfca668b..07f856fc 100644 --- a/samples/today/schema/AppointmentConnectionObject.h +++ b/samples/today/schema/AppointmentConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef APPOINTMENTCONNECTIONOBJECT_H -#define APPOINTMENTCONNECTIONOBJECT_H +#ifndef TODAY_APPOINTMENTCONNECTIONOBJECT_H +#define TODAY_APPOINTMENTCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] AppointmentConnection final } // namespace graphql::today::object -#endif // APPOINTMENTCONNECTIONOBJECT_H +#endif // TODAY_APPOINTMENTCONNECTIONOBJECT_H diff --git a/samples/today/schema/AppointmentEdgeObject.h b/samples/today/schema/AppointmentEdgeObject.h index d8c71b48..5f5d3c7c 100644 --- a/samples/today/schema/AppointmentEdgeObject.h +++ b/samples/today/schema/AppointmentEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef APPOINTMENTEDGEOBJECT_H -#define APPOINTMENTEDGEOBJECT_H +#ifndef TODAY_APPOINTMENTEDGEOBJECT_H +#define TODAY_APPOINTMENTEDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] AppointmentEdge final } // namespace graphql::today::object -#endif // APPOINTMENTEDGEOBJECT_H +#endif // TODAY_APPOINTMENTEDGEOBJECT_H diff --git a/samples/today/schema/AppointmentObject.h b/samples/today/schema/AppointmentObject.h index 0267f113..736e7a60 100644 --- a/samples/today/schema/AppointmentObject.h +++ b/samples/today/schema/AppointmentObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef APPOINTMENTOBJECT_H -#define APPOINTMENTOBJECT_H +#ifndef TODAY_APPOINTMENTOBJECT_H +#define TODAY_APPOINTMENTOBJECT_H #include "TodaySchema.h" @@ -266,4 +266,4 @@ class [[nodiscard("unnecessary construction")]] Appointment final } // namespace graphql::today::object -#endif // APPOINTMENTOBJECT_H +#endif // TODAY_APPOINTMENTOBJECT_H diff --git a/samples/today/schema/CompleteTaskPayloadObject.h b/samples/today/schema/CompleteTaskPayloadObject.h index ccac3881..bd85d417 100644 --- a/samples/today/schema/CompleteTaskPayloadObject.h +++ b/samples/today/schema/CompleteTaskPayloadObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef COMPLETETASKPAYLOADOBJECT_H -#define COMPLETETASKPAYLOADOBJECT_H +#ifndef TODAY_COMPLETETASKPAYLOADOBJECT_H +#define TODAY_COMPLETETASKPAYLOADOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] CompleteTaskPayload final } // namespace graphql::today::object -#endif // COMPLETETASKPAYLOADOBJECT_H +#endif // TODAY_COMPLETETASKPAYLOADOBJECT_H diff --git a/samples/today/schema/ExpensiveObject.h b/samples/today/schema/ExpensiveObject.h index bea1cd2c..2ad7e18f 100644 --- a/samples/today/schema/ExpensiveObject.h +++ b/samples/today/schema/ExpensiveObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef EXPENSIVEOBJECT_H -#define EXPENSIVEOBJECT_H +#ifndef TODAY_EXPENSIVEOBJECT_H +#define TODAY_EXPENSIVEOBJECT_H #include "TodaySchema.h" @@ -127,4 +127,4 @@ class [[nodiscard("unnecessary construction")]] Expensive final } // namespace graphql::today::object -#endif // EXPENSIVEOBJECT_H +#endif // TODAY_EXPENSIVEOBJECT_H diff --git a/samples/today/schema/FolderConnectionObject.h b/samples/today/schema/FolderConnectionObject.h index 61e6729f..92a5882a 100644 --- a/samples/today/schema/FolderConnectionObject.h +++ b/samples/today/schema/FolderConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef FOLDERCONNECTIONOBJECT_H -#define FOLDERCONNECTIONOBJECT_H +#ifndef TODAY_FOLDERCONNECTIONOBJECT_H +#define TODAY_FOLDERCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] FolderConnection final } // namespace graphql::today::object -#endif // FOLDERCONNECTIONOBJECT_H +#endif // TODAY_FOLDERCONNECTIONOBJECT_H diff --git a/samples/today/schema/FolderEdgeObject.h b/samples/today/schema/FolderEdgeObject.h index dc7a0d28..b132f8c1 100644 --- a/samples/today/schema/FolderEdgeObject.h +++ b/samples/today/schema/FolderEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef FOLDEREDGEOBJECT_H -#define FOLDEREDGEOBJECT_H +#ifndef TODAY_FOLDEREDGEOBJECT_H +#define TODAY_FOLDEREDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] FolderEdge final } // namespace graphql::today::object -#endif // FOLDEREDGEOBJECT_H +#endif // TODAY_FOLDEREDGEOBJECT_H diff --git a/samples/today/schema/FolderObject.h b/samples/today/schema/FolderObject.h index 2376bc55..69312e75 100644 --- a/samples/today/schema/FolderObject.h +++ b/samples/today/schema/FolderObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef FOLDEROBJECT_H -#define FOLDEROBJECT_H +#ifndef TODAY_FOLDEROBJECT_H +#define TODAY_FOLDEROBJECT_H #include "TodaySchema.h" @@ -206,4 +206,4 @@ class [[nodiscard("unnecessary construction")]] Folder final } // namespace graphql::today::object -#endif // FOLDEROBJECT_H +#endif // TODAY_FOLDEROBJECT_H diff --git a/samples/today/schema/MutationObject.h b/samples/today/schema/MutationObject.h index 0da072bc..b751f79b 100644 --- a/samples/today/schema/MutationObject.h +++ b/samples/today/schema/MutationObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef MUTATIONOBJECT_H -#define MUTATIONOBJECT_H +#ifndef TODAY_MUTATIONOBJECT_H +#define TODAY_MUTATIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] Mutation final } // namespace graphql::today::object -#endif // MUTATIONOBJECT_H +#endif // TODAY_MUTATIONOBJECT_H diff --git a/samples/today/schema/NestedTypeObject.h b/samples/today/schema/NestedTypeObject.h index 539f72db..e0d88c9b 100644 --- a/samples/today/schema/NestedTypeObject.h +++ b/samples/today/schema/NestedTypeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef NESTEDTYPEOBJECT_H -#define NESTEDTYPEOBJECT_H +#ifndef TODAY_NESTEDTYPEOBJECT_H +#define TODAY_NESTEDTYPEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] NestedType final } // namespace graphql::today::object -#endif // NESTEDTYPEOBJECT_H +#endif // TODAY_NESTEDTYPEOBJECT_H diff --git a/samples/today/schema/NodeObject.h b/samples/today/schema/NodeObject.h index 0310cdba..85f82969 100644 --- a/samples/today/schema/NodeObject.h +++ b/samples/today/schema/NodeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef NODEOBJECT_H -#define NODEOBJECT_H +#ifndef TODAY_NODEOBJECT_H +#define TODAY_NODEOBJECT_H #include "TodaySchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] Node final } // namespace graphql::today::object -#endif // NODEOBJECT_H +#endif // TODAY_NODEOBJECT_H diff --git a/samples/today/schema/PageInfoObject.h b/samples/today/schema/PageInfoObject.h index f4f10741..4b33b8ca 100644 --- a/samples/today/schema/PageInfoObject.h +++ b/samples/today/schema/PageInfoObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef PAGEINFOOBJECT_H -#define PAGEINFOOBJECT_H +#ifndef TODAY_PAGEINFOOBJECT_H +#define TODAY_PAGEINFOOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] PageInfo final } // namespace graphql::today::object -#endif // PAGEINFOOBJECT_H +#endif // TODAY_PAGEINFOOBJECT_H diff --git a/samples/today/schema/QueryObject.h b/samples/today/schema/QueryObject.h index 9a1226a4..167e1287 100644 --- a/samples/today/schema/QueryObject.h +++ b/samples/today/schema/QueryObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef QUERYOBJECT_H -#define QUERYOBJECT_H +#ifndef TODAY_QUERYOBJECT_H +#define TODAY_QUERYOBJECT_H #include "TodaySchema.h" @@ -491,4 +491,4 @@ class [[nodiscard("unnecessary construction")]] Query final } // namespace graphql::today::object -#endif // QUERYOBJECT_H +#endif // TODAY_QUERYOBJECT_H diff --git a/samples/today/schema/SubscriptionObject.h b/samples/today/schema/SubscriptionObject.h index c9179d85..c5bef36d 100644 --- a/samples/today/schema/SubscriptionObject.h +++ b/samples/today/schema/SubscriptionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef SUBSCRIPTIONOBJECT_H -#define SUBSCRIPTIONOBJECT_H +#ifndef TODAY_SUBSCRIPTIONOBJECT_H +#define TODAY_SUBSCRIPTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] Subscription final } // namespace graphql::today::object -#endif // SUBSCRIPTIONOBJECT_H +#endif // TODAY_SUBSCRIPTIONOBJECT_H diff --git a/samples/today/schema/TaskConnectionObject.h b/samples/today/schema/TaskConnectionObject.h index c82b2ae7..2ee84568 100644 --- a/samples/today/schema/TaskConnectionObject.h +++ b/samples/today/schema/TaskConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TASKCONNECTIONOBJECT_H -#define TASKCONNECTIONOBJECT_H +#ifndef TODAY_TASKCONNECTIONOBJECT_H +#define TODAY_TASKCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] TaskConnection final } // namespace graphql::today::object -#endif // TASKCONNECTIONOBJECT_H +#endif // TODAY_TASKCONNECTIONOBJECT_H diff --git a/samples/today/schema/TaskEdgeObject.h b/samples/today/schema/TaskEdgeObject.h index 4049d5c3..5d57eadf 100644 --- a/samples/today/schema/TaskEdgeObject.h +++ b/samples/today/schema/TaskEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TASKEDGEOBJECT_H -#define TASKEDGEOBJECT_H +#ifndef TODAY_TASKEDGEOBJECT_H +#define TODAY_TASKEDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] TaskEdge final } // namespace graphql::today::object -#endif // TASKEDGEOBJECT_H +#endif // TODAY_TASKEDGEOBJECT_H diff --git a/samples/today/schema/TaskObject.h b/samples/today/schema/TaskObject.h index 36548d0b..6214d27a 100644 --- a/samples/today/schema/TaskObject.h +++ b/samples/today/schema/TaskObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TASKOBJECT_H -#define TASKOBJECT_H +#ifndef TODAY_TASKOBJECT_H +#define TODAY_TASKOBJECT_H #include "TodaySchema.h" @@ -206,4 +206,4 @@ class [[nodiscard("unnecessary construction")]] Task final } // namespace graphql::today::object -#endif // TASKOBJECT_H +#endif // TODAY_TASKOBJECT_H diff --git a/samples/today/schema/UnionTypeObject.h b/samples/today/schema/UnionTypeObject.h index 1be8494e..0ee56b2b 100644 --- a/samples/today/schema/UnionTypeObject.h +++ b/samples/today/schema/UnionTypeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef UNIONTYPEOBJECT_H -#define UNIONTYPEOBJECT_H +#ifndef TODAY_UNIONTYPEOBJECT_H +#define TODAY_UNIONTYPEOBJECT_H #include "TodaySchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] UnionType final } // namespace graphql::today::object -#endif // UNIONTYPEOBJECT_H +#endif // TODAY_UNIONTYPEOBJECT_H diff --git a/samples/validation/schema/AlienObject.h b/samples/validation/schema/AlienObject.h index 1b627b50..2b34dc4f 100644 --- a/samples/validation/schema/AlienObject.h +++ b/samples/validation/schema/AlienObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef ALIENOBJECT_H -#define ALIENOBJECT_H +#ifndef VALIDATION_ALIENOBJECT_H +#define VALIDATION_ALIENOBJECT_H #include "ValidationSchema.h" @@ -176,4 +176,4 @@ class [[nodiscard("unnecessary construction")]] Alien final } // namespace graphql::validation::object -#endif // ALIENOBJECT_H +#endif // VALIDATION_ALIENOBJECT_H diff --git a/samples/validation/schema/ArgumentsObject.h b/samples/validation/schema/ArgumentsObject.h index b0ef4997..9bfeff3b 100644 --- a/samples/validation/schema/ArgumentsObject.h +++ b/samples/validation/schema/ArgumentsObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef ARGUMENTSOBJECT_H -#define ARGUMENTSOBJECT_H +#ifndef VALIDATION_ARGUMENTSOBJECT_H +#define VALIDATION_ARGUMENTSOBJECT_H #include "ValidationSchema.h" @@ -337,4 +337,4 @@ class [[nodiscard("unnecessary construction")]] Arguments final } // namespace graphql::validation::object -#endif // ARGUMENTSOBJECT_H +#endif // VALIDATION_ARGUMENTSOBJECT_H diff --git a/samples/validation/schema/CatObject.h b/samples/validation/schema/CatObject.h index f9e03753..1dca910a 100644 --- a/samples/validation/schema/CatObject.h +++ b/samples/validation/schema/CatObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef CATOBJECT_H -#define CATOBJECT_H +#ifndef VALIDATION_CATOBJECT_H +#define VALIDATION_CATOBJECT_H #include "ValidationSchema.h" @@ -236,4 +236,4 @@ class [[nodiscard("unnecessary construction")]] Cat final } // namespace graphql::validation::object -#endif // CATOBJECT_H +#endif // VALIDATION_CATOBJECT_H diff --git a/samples/validation/schema/CatOrDogObject.h b/samples/validation/schema/CatOrDogObject.h index dce444bb..fa0d89e6 100644 --- a/samples/validation/schema/CatOrDogObject.h +++ b/samples/validation/schema/CatOrDogObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef CATORDOGOBJECT_H -#define CATORDOGOBJECT_H +#ifndef VALIDATION_CATORDOGOBJECT_H +#define VALIDATION_CATORDOGOBJECT_H #include "ValidationSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] CatOrDog final } // namespace graphql::validation::object -#endif // CATORDOGOBJECT_H +#endif // VALIDATION_CATORDOGOBJECT_H diff --git a/samples/validation/schema/DogObject.h b/samples/validation/schema/DogObject.h index 4b7fc5b8..b31942ec 100644 --- a/samples/validation/schema/DogObject.h +++ b/samples/validation/schema/DogObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef DOGOBJECT_H -#define DOGOBJECT_H +#ifndef VALIDATION_DOGOBJECT_H +#define VALIDATION_DOGOBJECT_H #include "ValidationSchema.h" @@ -297,4 +297,4 @@ class [[nodiscard("unnecessary construction")]] Dog final } // namespace graphql::validation::object -#endif // DOGOBJECT_H +#endif // VALIDATION_DOGOBJECT_H diff --git a/samples/validation/schema/DogOrHumanObject.h b/samples/validation/schema/DogOrHumanObject.h index 3f227aff..9bc5b046 100644 --- a/samples/validation/schema/DogOrHumanObject.h +++ b/samples/validation/schema/DogOrHumanObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef DOGORHUMANOBJECT_H -#define DOGORHUMANOBJECT_H +#ifndef VALIDATION_DOGORHUMANOBJECT_H +#define VALIDATION_DOGORHUMANOBJECT_H #include "ValidationSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] DogOrHuman final } // namespace graphql::validation::object -#endif // DOGORHUMANOBJECT_H +#endif // VALIDATION_DOGORHUMANOBJECT_H diff --git a/samples/validation/schema/HumanObject.h b/samples/validation/schema/HumanObject.h index f9d54db5..ebc1ecb4 100644 --- a/samples/validation/schema/HumanObject.h +++ b/samples/validation/schema/HumanObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef HUMANOBJECT_H -#define HUMANOBJECT_H +#ifndef VALIDATION_HUMANOBJECT_H +#define VALIDATION_HUMANOBJECT_H #include "ValidationSchema.h" @@ -177,4 +177,4 @@ class [[nodiscard("unnecessary construction")]] Human final } // namespace graphql::validation::object -#endif // HUMANOBJECT_H +#endif // VALIDATION_HUMANOBJECT_H diff --git a/samples/validation/schema/HumanOrAlienObject.h b/samples/validation/schema/HumanOrAlienObject.h index c98320cd..1a77214a 100644 --- a/samples/validation/schema/HumanOrAlienObject.h +++ b/samples/validation/schema/HumanOrAlienObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef HUMANORALIENOBJECT_H -#define HUMANORALIENOBJECT_H +#ifndef VALIDATION_HUMANORALIENOBJECT_H +#define VALIDATION_HUMANORALIENOBJECT_H #include "ValidationSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] HumanOrAlien final } // namespace graphql::validation::object -#endif // HUMANORALIENOBJECT_H +#endif // VALIDATION_HUMANORALIENOBJECT_H diff --git a/samples/validation/schema/MessageObject.h b/samples/validation/schema/MessageObject.h index c7ff067b..d01e45ff 100644 --- a/samples/validation/schema/MessageObject.h +++ b/samples/validation/schema/MessageObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef MESSAGEOBJECT_H -#define MESSAGEOBJECT_H +#ifndef VALIDATION_MESSAGEOBJECT_H +#define VALIDATION_MESSAGEOBJECT_H #include "ValidationSchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] Message final } // namespace graphql::validation::object -#endif // MESSAGEOBJECT_H +#endif // VALIDATION_MESSAGEOBJECT_H diff --git a/samples/validation/schema/MutateDogResultObject.h b/samples/validation/schema/MutateDogResultObject.h index e23bc62c..f7163d4b 100644 --- a/samples/validation/schema/MutateDogResultObject.h +++ b/samples/validation/schema/MutateDogResultObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef MUTATEDOGRESULTOBJECT_H -#define MUTATEDOGRESULTOBJECT_H +#ifndef VALIDATION_MUTATEDOGRESULTOBJECT_H +#define VALIDATION_MUTATEDOGRESULTOBJECT_H #include "ValidationSchema.h" @@ -127,4 +127,4 @@ class [[nodiscard("unnecessary construction")]] MutateDogResult final } // namespace graphql::validation::object -#endif // MUTATEDOGRESULTOBJECT_H +#endif // VALIDATION_MUTATEDOGRESULTOBJECT_H diff --git a/samples/validation/schema/MutationObject.h b/samples/validation/schema/MutationObject.h index 99a7e3e7..885e5dfe 100644 --- a/samples/validation/schema/MutationObject.h +++ b/samples/validation/schema/MutationObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef MUTATIONOBJECT_H -#define MUTATIONOBJECT_H +#ifndef VALIDATION_MUTATIONOBJECT_H +#define VALIDATION_MUTATIONOBJECT_H #include "ValidationSchema.h" @@ -127,4 +127,4 @@ class [[nodiscard("unnecessary construction")]] Mutation final } // namespace graphql::validation::object -#endif // MUTATIONOBJECT_H +#endif // VALIDATION_MUTATIONOBJECT_H diff --git a/samples/validation/schema/NodeObject.h b/samples/validation/schema/NodeObject.h index feb5d5f5..228b6c4f 100644 --- a/samples/validation/schema/NodeObject.h +++ b/samples/validation/schema/NodeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef NODEOBJECT_H -#define NODEOBJECT_H +#ifndef VALIDATION_NODEOBJECT_H +#define VALIDATION_NODEOBJECT_H #include "ValidationSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] Node final } // namespace graphql::validation::object -#endif // NODEOBJECT_H +#endif // VALIDATION_NODEOBJECT_H diff --git a/samples/validation/schema/PetObject.h b/samples/validation/schema/PetObject.h index 0bd8d73c..44371729 100644 --- a/samples/validation/schema/PetObject.h +++ b/samples/validation/schema/PetObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef PETOBJECT_H -#define PETOBJECT_H +#ifndef VALIDATION_PETOBJECT_H +#define VALIDATION_PETOBJECT_H #include "ValidationSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] Pet final } // namespace graphql::validation::object -#endif // PETOBJECT_H +#endif // VALIDATION_PETOBJECT_H diff --git a/samples/validation/schema/QueryObject.h b/samples/validation/schema/QueryObject.h index 709a05bf..50b145f4 100644 --- a/samples/validation/schema/QueryObject.h +++ b/samples/validation/schema/QueryObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef QUERYOBJECT_H -#define QUERYOBJECT_H +#ifndef VALIDATION_QUERYOBJECT_H +#define VALIDATION_QUERYOBJECT_H #include "ValidationSchema.h" @@ -337,4 +337,4 @@ class [[nodiscard("unnecessary construction")]] Query final } // namespace graphql::validation::object -#endif // QUERYOBJECT_H +#endif // VALIDATION_QUERYOBJECT_H diff --git a/samples/validation/schema/ResourceObject.h b/samples/validation/schema/ResourceObject.h index 1a28b4f4..002b5a1c 100644 --- a/samples/validation/schema/ResourceObject.h +++ b/samples/validation/schema/ResourceObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef RESOURCEOBJECT_H -#define RESOURCEOBJECT_H +#ifndef VALIDATION_RESOURCEOBJECT_H +#define VALIDATION_RESOURCEOBJECT_H #include "ValidationSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] Resource final } // namespace graphql::validation::object -#endif // RESOURCEOBJECT_H +#endif // VALIDATION_RESOURCEOBJECT_H diff --git a/samples/validation/schema/SentientObject.h b/samples/validation/schema/SentientObject.h index be4ca01d..9d596491 100644 --- a/samples/validation/schema/SentientObject.h +++ b/samples/validation/schema/SentientObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef SENTIENTOBJECT_H -#define SENTIENTOBJECT_H +#ifndef VALIDATION_SENTIENTOBJECT_H +#define VALIDATION_SENTIENTOBJECT_H #include "ValidationSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] Sentient final } // namespace graphql::validation::object -#endif // SENTIENTOBJECT_H +#endif // VALIDATION_SENTIENTOBJECT_H diff --git a/samples/validation/schema/SubscriptionObject.h b/samples/validation/schema/SubscriptionObject.h index 59358465..bb7ea834 100644 --- a/samples/validation/schema/SubscriptionObject.h +++ b/samples/validation/schema/SubscriptionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef SUBSCRIPTIONOBJECT_H -#define SUBSCRIPTIONOBJECT_H +#ifndef VALIDATION_SUBSCRIPTIONOBJECT_H +#define VALIDATION_SUBSCRIPTIONOBJECT_H #include "ValidationSchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] Subscription final } // namespace graphql::validation::object -#endif // SUBSCRIPTIONOBJECT_H +#endif // VALIDATION_SUBSCRIPTIONOBJECT_H diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 38a6d248..b3749689 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -2488,7 +2488,8 @@ Operations::Operations()cpp"; )cpp"; } sourceFile << R"cpp(}, )cpp" - << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") << R"cpp()); + << (directive.isRepeatable ? R"cpp(true)cpp" : R"cpp(false)cpp") + << R"cpp()); )cpp"; } } @@ -3417,7 +3418,8 @@ std::vector Generator::outputSeparateFiles() const noexcept { std::ofstream headerFile(headerPath, std::ios_base::trunc); - IncludeGuardScope includeGuard { headerFile, headerFilename }; + IncludeGuardScope includeGuard { headerFile, + std::format("{}_{}", _loader.getFilenamePrefix(), headerFilename) }; headerFile << R"cpp(#include ")cpp" << std::filesystem::path(_schemaHeaderPath).filename().string() << R"cpp(" @@ -3501,7 +3503,8 @@ using namespace std::literals; { std::ofstream headerFile(headerPath, std::ios_base::trunc); - IncludeGuardScope includeGuard { headerFile, headerFilename }; + IncludeGuardScope includeGuard { headerFile, + std::format("{}_{}", _loader.getFilenamePrefix(), headerFilename) }; headerFile << R"cpp(#include ")cpp" << std::filesystem::path(_schemaHeaderPath).filename().string() << R"cpp(" @@ -3605,7 +3608,8 @@ using namespace std::literals; { std::ofstream headerFile(headerPath, std::ios_base::trunc); - IncludeGuardScope includeGuard { headerFile, headerFilename }; + IncludeGuardScope includeGuard { headerFile, + std::format("{}_{}", _loader.getFilenamePrefix(), headerFilename) }; headerFile << R"cpp(#include ")cpp" << std::filesystem::path(_schemaHeaderPath).filename().string() << R"cpp(" diff --git a/src/introspection/DirectiveObject.h b/src/introspection/DirectiveObject.h index 20a0620e..f9714caf 100644 --- a/src/introspection/DirectiveObject.h +++ b/src/introspection/DirectiveObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef DIRECTIVEOBJECT_H -#define DIRECTIVEOBJECT_H +#ifndef INTROSPECTION_DIRECTIVEOBJECT_H +#define INTROSPECTION_DIRECTIVEOBJECT_H #include "IntrospectionSchema.h" @@ -85,4 +85,4 @@ class [[nodiscard("unnecessary construction")]] Directive final } // namespace graphql::introspection::object -#endif // DIRECTIVEOBJECT_H +#endif // INTROSPECTION_DIRECTIVEOBJECT_H diff --git a/src/introspection/EnumValueObject.h b/src/introspection/EnumValueObject.h index 0ac9e74f..a97c9534 100644 --- a/src/introspection/EnumValueObject.h +++ b/src/introspection/EnumValueObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef ENUMVALUEOBJECT_H -#define ENUMVALUEOBJECT_H +#ifndef INTROSPECTION_ENUMVALUEOBJECT_H +#define INTROSPECTION_ENUMVALUEOBJECT_H #include "IntrospectionSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] EnumValue final } // namespace graphql::introspection::object -#endif // ENUMVALUEOBJECT_H +#endif // INTROSPECTION_ENUMVALUEOBJECT_H diff --git a/src/introspection/FieldObject.h b/src/introspection/FieldObject.h index f835c5ae..07fba6ae 100644 --- a/src/introspection/FieldObject.h +++ b/src/introspection/FieldObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef FIELDOBJECT_H -#define FIELDOBJECT_H +#ifndef INTROSPECTION_FIELDOBJECT_H +#define INTROSPECTION_FIELDOBJECT_H #include "IntrospectionSchema.h" @@ -92,4 +92,4 @@ class [[nodiscard("unnecessary construction")]] Field final } // namespace graphql::introspection::object -#endif // FIELDOBJECT_H +#endif // INTROSPECTION_FIELDOBJECT_H diff --git a/src/introspection/InputValueObject.h b/src/introspection/InputValueObject.h index 70faa321..8dda3e79 100644 --- a/src/introspection/InputValueObject.h +++ b/src/introspection/InputValueObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef INPUTVALUEOBJECT_H -#define INPUTVALUEOBJECT_H +#ifndef INTROSPECTION_INPUTVALUEOBJECT_H +#define INTROSPECTION_INPUTVALUEOBJECT_H #include "IntrospectionSchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] InputValue final } // namespace graphql::introspection::object -#endif // INPUTVALUEOBJECT_H +#endif // INTROSPECTION_INPUTVALUEOBJECT_H diff --git a/src/introspection/SchemaObject.h b/src/introspection/SchemaObject.h index fd3659c1..53b12b69 100644 --- a/src/introspection/SchemaObject.h +++ b/src/introspection/SchemaObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef SCHEMAOBJECT_H -#define SCHEMAOBJECT_H +#ifndef INTROSPECTION_SCHEMAOBJECT_H +#define INTROSPECTION_SCHEMAOBJECT_H #include "IntrospectionSchema.h" @@ -92,4 +92,4 @@ class [[nodiscard("unnecessary construction")]] Schema final } // namespace graphql::introspection::object -#endif // SCHEMAOBJECT_H +#endif // INTROSPECTION_SCHEMAOBJECT_H diff --git a/src/introspection/TypeObject.h b/src/introspection/TypeObject.h index 3b350e1c..993e6dd7 100644 --- a/src/introspection/TypeObject.h +++ b/src/introspection/TypeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TYPEOBJECT_H -#define TYPEOBJECT_H +#ifndef INTROSPECTION_TYPEOBJECT_H +#define INTROSPECTION_TYPEOBJECT_H #include "IntrospectionSchema.h" @@ -120,4 +120,4 @@ class [[nodiscard("unnecessary construction")]] Type final } // namespace graphql::introspection::object -#endif // TYPEOBJECT_H +#endif // INTROSPECTION_TYPEOBJECT_H From 8d328c93e75df025d241b3e3345871f266688c78 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 25 Oct 2024 19:12:37 -0700 Subject: [PATCH 108/123] fix: simplify includes in StitchedSchema.cpp --- samples/stitched/StitchedSchema.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/samples/stitched/StitchedSchema.cpp b/samples/stitched/StitchedSchema.cpp index 1e1dd588..7466e4ae 100644 --- a/samples/stitched/StitchedSchema.cpp +++ b/samples/stitched/StitchedSchema.cpp @@ -4,9 +4,7 @@ #include "StitchedSchema.h" #include "StarWarsData.h" -#include "StarWarsSchema.h" - -import GraphQL.Today.Mock; +#include "TodayMock.h" namespace graphql::stitched { From 11426cad8daf4fc82e9ec2a111173f0918335878 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Fri, 25 Oct 2024 19:33:00 -0700 Subject: [PATCH 109/123] fix: add schemagen --prefix-headers option --- include/SchemaGenerator.h | 1 + samples/today/TodayMock.cpp | 14 +++--- samples/today/TodayMock.h | 22 ++++----- .../AppointmentConnectionObject.cpp | 6 +-- .../AppointmentConnectionObject.ixx | 2 +- .../nointrospection/AppointmentEdgeObject.cpp | 4 +- .../nointrospection/AppointmentEdgeObject.ixx | 2 +- .../nointrospection/AppointmentObject.cpp | 2 +- .../nointrospection/AppointmentObject.ixx | 2 +- samples/today/nointrospection/CMakeLists.txt | 2 +- .../CompleteTaskPayloadObject.cpp | 4 +- .../CompleteTaskPayloadObject.ixx | 2 +- .../today/nointrospection/ExpensiveObject.cpp | 2 +- .../today/nointrospection/ExpensiveObject.ixx | 2 +- .../FolderConnectionObject.cpp | 6 +-- .../FolderConnectionObject.ixx | 2 +- .../nointrospection/FolderEdgeObject.cpp | 4 +- .../nointrospection/FolderEdgeObject.ixx | 2 +- .../today/nointrospection/FolderObject.cpp | 2 +- .../today/nointrospection/FolderObject.ixx | 2 +- .../today/nointrospection/MutationObject.cpp | 4 +- .../today/nointrospection/MutationObject.ixx | 2 +- .../nointrospection/NestedTypeObject.cpp | 4 +- .../nointrospection/NestedTypeObject.ixx | 2 +- samples/today/nointrospection/NodeObject.cpp | 2 +- samples/today/nointrospection/NodeObject.ixx | 2 +- .../today/nointrospection/PageInfoObject.cpp | 2 +- .../today/nointrospection/PageInfoObject.ixx | 2 +- samples/today/nointrospection/QueryObject.cpp | 22 ++++----- samples/today/nointrospection/QueryObject.ixx | 2 +- .../nointrospection/SubscriptionObject.cpp | 6 +-- .../nointrospection/SubscriptionObject.ixx | 2 +- .../nointrospection/TaskConnectionObject.cpp | 6 +-- .../nointrospection/TaskConnectionObject.ixx | 2 +- .../today/nointrospection/TaskEdgeObject.cpp | 4 +- .../today/nointrospection/TaskEdgeObject.ixx | 2 +- samples/today/nointrospection/TaskObject.cpp | 2 +- samples/today/nointrospection/TaskObject.ixx | 2 +- ...t.h => TodayAppointmentConnectionObject.h} | 6 +-- ...eObject.h => TodayAppointmentEdgeObject.h} | 6 +-- ...tmentObject.h => TodayAppointmentObject.h} | 6 +-- .../TodayCompleteTaskPayloadObject.h} | 6 +-- .../TodayExpensiveObject.h} | 6 +-- .../TodayFolderConnectionObject.h} | 6 +-- ...erEdgeObject.h => TodayFolderEdgeObject.h} | 6 +-- .../{FolderObject.h => TodayFolderObject.h} | 6 +-- .../TodayMutationObject.h} | 6 +-- ...edTypeObject.h => TodayNestedTypeObject.h} | 6 +-- .../TodayNodeObject.h} | 6 +-- .../TodayPageInfoObject.h} | 6 +-- .../{QueryObject.h => TodayQueryObject.h} | 6 +-- samples/today/nointrospection/TodaySchema.cpp | 6 +-- .../TodaySubscriptionObject.h} | 6 +-- ...onObject.h => TodayTaskConnectionObject.h} | 6 +-- .../TodayTaskEdgeObject.h} | 6 +-- .../{TaskObject.h => TodayTaskObject.h} | 6 +-- ...ionTypeObject.h => TodayUnionTypeObject.h} | 6 +-- .../today/nointrospection/UnionTypeObject.cpp | 2 +- .../today/nointrospection/UnionTypeObject.ixx | 2 +- .../schema/AppointmentConnectionObject.cpp | 6 +-- .../schema/AppointmentConnectionObject.ixx | 2 +- .../today/schema/AppointmentEdgeObject.cpp | 4 +- .../today/schema/AppointmentEdgeObject.ixx | 2 +- samples/today/schema/AppointmentObject.cpp | 2 +- samples/today/schema/AppointmentObject.ixx | 2 +- samples/today/schema/CMakeLists.txt | 2 +- .../schema/CompleteTaskPayloadObject.cpp | 4 +- .../schema/CompleteTaskPayloadObject.ixx | 2 +- samples/today/schema/ExpensiveObject.cpp | 2 +- samples/today/schema/ExpensiveObject.ixx | 2 +- .../today/schema/FolderConnectionObject.cpp | 6 +-- .../today/schema/FolderConnectionObject.ixx | 2 +- samples/today/schema/FolderEdgeObject.cpp | 4 +- samples/today/schema/FolderEdgeObject.ixx | 2 +- samples/today/schema/FolderObject.cpp | 2 +- samples/today/schema/FolderObject.ixx | 2 +- samples/today/schema/MutationObject.cpp | 4 +- samples/today/schema/MutationObject.ixx | 2 +- samples/today/schema/NestedTypeObject.cpp | 4 +- samples/today/schema/NestedTypeObject.ixx | 2 +- samples/today/schema/NodeObject.cpp | 2 +- samples/today/schema/NodeObject.ixx | 2 +- samples/today/schema/PageInfoObject.cpp | 2 +- samples/today/schema/PageInfoObject.ixx | 2 +- samples/today/schema/QueryObject.cpp | 22 ++++----- samples/today/schema/QueryObject.ixx | 2 +- samples/today/schema/SubscriptionObject.cpp | 6 +-- samples/today/schema/SubscriptionObject.ixx | 2 +- samples/today/schema/TaskConnectionObject.cpp | 6 +-- samples/today/schema/TaskConnectionObject.ixx | 2 +- samples/today/schema/TaskEdgeObject.cpp | 4 +- samples/today/schema/TaskEdgeObject.ixx | 2 +- samples/today/schema/TaskObject.cpp | 2 +- samples/today/schema/TaskObject.ixx | 2 +- ...t.h => TodayAppointmentConnectionObject.h} | 6 +-- ...eObject.h => TodayAppointmentEdgeObject.h} | 6 +-- ...tmentObject.h => TodayAppointmentObject.h} | 6 +-- .../TodayCompleteTaskPayloadObject.h} | 6 +-- .../TodayExpensiveObject.h} | 6 +-- .../TodayFolderConnectionObject.h} | 6 +-- ...erEdgeObject.h => TodayFolderEdgeObject.h} | 6 +-- .../{FolderObject.h => TodayFolderObject.h} | 6 +-- .../TodayMutationObject.h} | 6 +-- ...edTypeObject.h => TodayNestedTypeObject.h} | 6 +-- .../NodeObject.h => schema/TodayNodeObject.h} | 6 +-- .../TodayPageInfoObject.h} | 6 +-- .../{QueryObject.h => TodayQueryObject.h} | 6 +-- samples/today/schema/TodaySchema.cpp | 6 +-- .../TodaySubscriptionObject.h} | 6 +-- ...onObject.h => TodayTaskConnectionObject.h} | 6 +-- .../TodayTaskEdgeObject.h} | 6 +-- .../{TaskObject.h => TodayTaskObject.h} | 6 +-- ...ionTypeObject.h => TodayUnionTypeObject.h} | 6 +-- samples/today/schema/UnionTypeObject.cpp | 2 +- samples/today/schema/UnionTypeObject.ixx | 2 +- src/SchemaGenerator.cpp | 47 +++++++++++++++---- 116 files changed, 293 insertions(+), 263 deletions(-) rename samples/today/nointrospection/{AppointmentConnectionObject.h => TodayAppointmentConnectionObject.h} (97%) rename samples/today/nointrospection/{AppointmentEdgeObject.h => TodayAppointmentEdgeObject.h} (97%) rename samples/today/nointrospection/{AppointmentObject.h => TodayAppointmentObject.h} (98%) rename samples/today/{schema/CompleteTaskPayloadObject.h => nointrospection/TodayCompleteTaskPayloadObject.h} (97%) rename samples/today/{schema/ExpensiveObject.h => nointrospection/TodayExpensiveObject.h} (96%) rename samples/today/{schema/FolderConnectionObject.h => nointrospection/TodayFolderConnectionObject.h} (97%) rename samples/today/nointrospection/{FolderEdgeObject.h => TodayFolderEdgeObject.h} (97%) rename samples/today/nointrospection/{FolderObject.h => TodayFolderObject.h} (98%) rename samples/today/{schema/MutationObject.h => nointrospection/TodayMutationObject.h} (97%) rename samples/today/nointrospection/{NestedTypeObject.h => TodayNestedTypeObject.h} (97%) rename samples/today/{schema/NodeObject.h => nointrospection/TodayNodeObject.h} (95%) rename samples/today/{schema/PageInfoObject.h => nointrospection/TodayPageInfoObject.h} (97%) rename samples/today/nointrospection/{QueryObject.h => TodayQueryObject.h} (99%) rename samples/today/{schema/SubscriptionObject.h => nointrospection/TodaySubscriptionObject.h} (97%) rename samples/today/nointrospection/{TaskConnectionObject.h => TodayTaskConnectionObject.h} (97%) rename samples/today/{schema/TaskEdgeObject.h => nointrospection/TodayTaskEdgeObject.h} (97%) rename samples/today/nointrospection/{TaskObject.h => TodayTaskObject.h} (98%) rename samples/today/nointrospection/{UnionTypeObject.h => TodayUnionTypeObject.h} (95%) rename samples/today/schema/{AppointmentConnectionObject.h => TodayAppointmentConnectionObject.h} (97%) rename samples/today/schema/{AppointmentEdgeObject.h => TodayAppointmentEdgeObject.h} (97%) rename samples/today/schema/{AppointmentObject.h => TodayAppointmentObject.h} (98%) rename samples/today/{nointrospection/CompleteTaskPayloadObject.h => schema/TodayCompleteTaskPayloadObject.h} (97%) rename samples/today/{nointrospection/ExpensiveObject.h => schema/TodayExpensiveObject.h} (96%) rename samples/today/{nointrospection/FolderConnectionObject.h => schema/TodayFolderConnectionObject.h} (97%) rename samples/today/schema/{FolderEdgeObject.h => TodayFolderEdgeObject.h} (97%) rename samples/today/schema/{FolderObject.h => TodayFolderObject.h} (98%) rename samples/today/{nointrospection/MutationObject.h => schema/TodayMutationObject.h} (97%) rename samples/today/schema/{NestedTypeObject.h => TodayNestedTypeObject.h} (97%) rename samples/today/{nointrospection/NodeObject.h => schema/TodayNodeObject.h} (95%) rename samples/today/{nointrospection/PageInfoObject.h => schema/TodayPageInfoObject.h} (97%) rename samples/today/schema/{QueryObject.h => TodayQueryObject.h} (99%) rename samples/today/{nointrospection/SubscriptionObject.h => schema/TodaySubscriptionObject.h} (97%) rename samples/today/schema/{TaskConnectionObject.h => TodayTaskConnectionObject.h} (97%) rename samples/today/{nointrospection/TaskEdgeObject.h => schema/TodayTaskEdgeObject.h} (97%) rename samples/today/schema/{TaskObject.h => TodayTaskObject.h} (98%) rename samples/today/schema/{UnionTypeObject.h => TodayUnionTypeObject.h} (95%) diff --git a/include/SchemaGenerator.h b/include/SchemaGenerator.h index 561dc01c..7edabf18 100644 --- a/include/SchemaGenerator.h +++ b/include/SchemaGenerator.h @@ -24,6 +24,7 @@ struct [[nodiscard("unnecessary construction")]] GeneratorOptions const bool verbose = false; const bool stubs = false; const bool noIntrospection = false; + const bool prefixedHeaders = false; }; class [[nodiscard("unnecessary construction")]] Generator diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index 1d02e4b4..62d06c50 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -3,13 +3,13 @@ #include "TodayMock.h" -#include "AppointmentConnectionObject.h" -#include "CompleteTaskPayloadObject.h" -#include "ExpensiveObject.h" -#include "FolderConnectionObject.h" -#include "NestedTypeObject.h" -#include "TaskConnectionObject.h" -#include "UnionTypeObject.h" +#include "TodayAppointmentConnectionObject.h" +#include "TodayCompleteTaskPayloadObject.h" +#include "TodayExpensiveObject.h" +#include "TodayFolderConnectionObject.h" +#include "TodayNestedTypeObject.h" +#include "TodayTaskConnectionObject.h" +#include "TodayUnionTypeObject.h" #include #include diff --git a/samples/today/TodayMock.h b/samples/today/TodayMock.h index 7142dc6e..3ccf15b1 100644 --- a/samples/today/TodayMock.h +++ b/samples/today/TodayMock.h @@ -8,17 +8,17 @@ #include "TodaySchema.h" -#include "AppointmentEdgeObject.h" -#include "AppointmentObject.h" -#include "FolderEdgeObject.h" -#include "FolderObject.h" -#include "MutationObject.h" -#include "NodeObject.h" -#include "PageInfoObject.h" -#include "QueryObject.h" -#include "SubscriptionObject.h" -#include "TaskEdgeObject.h" -#include "TaskObject.h" +#include "TodayAppointmentEdgeObject.h" +#include "TodayAppointmentObject.h" +#include "TodayFolderEdgeObject.h" +#include "TodayFolderObject.h" +#include "TodayMutationObject.h" +#include "TodayNodeObject.h" +#include "TodayPageInfoObject.h" +#include "TodayQueryObject.h" +#include "TodaySubscriptionObject.h" +#include "TodayTaskEdgeObject.h" +#include "TodayTaskObject.h" #include #include diff --git a/samples/today/nointrospection/AppointmentConnectionObject.cpp b/samples/today/nointrospection/AppointmentConnectionObject.cpp index 9ea706b8..ad970e9c 100644 --- a/samples/today/nointrospection/AppointmentConnectionObject.cpp +++ b/samples/today/nointrospection/AppointmentConnectionObject.cpp @@ -3,9 +3,9 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "AppointmentConnectionObject.h" -#include "PageInfoObject.h" -#include "AppointmentEdgeObject.h" +#include "TodayAppointmentConnectionObject.h" +#include "TodayPageInfoObject.h" +#include "TodayAppointmentEdgeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/AppointmentConnectionObject.ixx b/samples/today/nointrospection/AppointmentConnectionObject.ixx index ec982810..3f73da58 100644 --- a/samples/today/nointrospection/AppointmentConnectionObject.ixx +++ b/samples/today/nointrospection/AppointmentConnectionObject.ixx @@ -5,7 +5,7 @@ module; -#include "AppointmentConnectionObject.h" +#include "TodayAppointmentConnectionObject.h" export module GraphQL.Today.AppointmentConnectionObject; diff --git a/samples/today/nointrospection/AppointmentEdgeObject.cpp b/samples/today/nointrospection/AppointmentEdgeObject.cpp index b79f8a66..1aa60cf4 100644 --- a/samples/today/nointrospection/AppointmentEdgeObject.cpp +++ b/samples/today/nointrospection/AppointmentEdgeObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "AppointmentEdgeObject.h" -#include "AppointmentObject.h" +#include "TodayAppointmentEdgeObject.h" +#include "TodayAppointmentObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/AppointmentEdgeObject.ixx b/samples/today/nointrospection/AppointmentEdgeObject.ixx index 8d283bf9..46a48b9e 100644 --- a/samples/today/nointrospection/AppointmentEdgeObject.ixx +++ b/samples/today/nointrospection/AppointmentEdgeObject.ixx @@ -5,7 +5,7 @@ module; -#include "AppointmentEdgeObject.h" +#include "TodayAppointmentEdgeObject.h" export module GraphQL.Today.AppointmentEdgeObject; diff --git a/samples/today/nointrospection/AppointmentObject.cpp b/samples/today/nointrospection/AppointmentObject.cpp index 4ff77df9..39f8910e 100644 --- a/samples/today/nointrospection/AppointmentObject.cpp +++ b/samples/today/nointrospection/AppointmentObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "AppointmentObject.h" +#include "TodayAppointmentObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/AppointmentObject.ixx b/samples/today/nointrospection/AppointmentObject.ixx index 34131b4b..2fc474d8 100644 --- a/samples/today/nointrospection/AppointmentObject.ixx +++ b/samples/today/nointrospection/AppointmentObject.ixx @@ -5,7 +5,7 @@ module; -#include "AppointmentObject.h" +#include "TodayAppointmentObject.h" export module GraphQL.Today.AppointmentObject; diff --git a/samples/today/nointrospection/CMakeLists.txt b/samples/today/nointrospection/CMakeLists.txt index 5f98c0c0..b4376710 100644 --- a/samples/today/nointrospection/CMakeLists.txt +++ b/samples/today/nointrospection/CMakeLists.txt @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.28) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) if(GRAPHQL_UPDATE_SAMPLES) - update_graphql_schema_files(today_nointrospection ../schema.today.graphql Today today --stubs --no-introspection) + update_graphql_schema_files(today_nointrospection ../schema.today.graphql Today today --stubs --no-introspection --prefix-headers) endif() add_graphql_schema_target(today_nointrospection) diff --git a/samples/today/nointrospection/CompleteTaskPayloadObject.cpp b/samples/today/nointrospection/CompleteTaskPayloadObject.cpp index 584a011d..3052500b 100644 --- a/samples/today/nointrospection/CompleteTaskPayloadObject.cpp +++ b/samples/today/nointrospection/CompleteTaskPayloadObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "CompleteTaskPayloadObject.h" -#include "TaskObject.h" +#include "TodayCompleteTaskPayloadObject.h" +#include "TodayTaskObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/CompleteTaskPayloadObject.ixx b/samples/today/nointrospection/CompleteTaskPayloadObject.ixx index fe9415d9..f32cd43c 100644 --- a/samples/today/nointrospection/CompleteTaskPayloadObject.ixx +++ b/samples/today/nointrospection/CompleteTaskPayloadObject.ixx @@ -5,7 +5,7 @@ module; -#include "CompleteTaskPayloadObject.h" +#include "TodayCompleteTaskPayloadObject.h" export module GraphQL.Today.CompleteTaskPayloadObject; diff --git a/samples/today/nointrospection/ExpensiveObject.cpp b/samples/today/nointrospection/ExpensiveObject.cpp index 6c984f82..7c359517 100644 --- a/samples/today/nointrospection/ExpensiveObject.cpp +++ b/samples/today/nointrospection/ExpensiveObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "ExpensiveObject.h" +#include "TodayExpensiveObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/ExpensiveObject.ixx b/samples/today/nointrospection/ExpensiveObject.ixx index 00bf65f4..8cdea947 100644 --- a/samples/today/nointrospection/ExpensiveObject.ixx +++ b/samples/today/nointrospection/ExpensiveObject.ixx @@ -5,7 +5,7 @@ module; -#include "ExpensiveObject.h" +#include "TodayExpensiveObject.h" export module GraphQL.Today.ExpensiveObject; diff --git a/samples/today/nointrospection/FolderConnectionObject.cpp b/samples/today/nointrospection/FolderConnectionObject.cpp index 78fd9094..334dcf14 100644 --- a/samples/today/nointrospection/FolderConnectionObject.cpp +++ b/samples/today/nointrospection/FolderConnectionObject.cpp @@ -3,9 +3,9 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "FolderConnectionObject.h" -#include "PageInfoObject.h" -#include "FolderEdgeObject.h" +#include "TodayFolderConnectionObject.h" +#include "TodayPageInfoObject.h" +#include "TodayFolderEdgeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/FolderConnectionObject.ixx b/samples/today/nointrospection/FolderConnectionObject.ixx index d5434681..1a8e93ea 100644 --- a/samples/today/nointrospection/FolderConnectionObject.ixx +++ b/samples/today/nointrospection/FolderConnectionObject.ixx @@ -5,7 +5,7 @@ module; -#include "FolderConnectionObject.h" +#include "TodayFolderConnectionObject.h" export module GraphQL.Today.FolderConnectionObject; diff --git a/samples/today/nointrospection/FolderEdgeObject.cpp b/samples/today/nointrospection/FolderEdgeObject.cpp index 179e4c37..5e2e341f 100644 --- a/samples/today/nointrospection/FolderEdgeObject.cpp +++ b/samples/today/nointrospection/FolderEdgeObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "FolderEdgeObject.h" -#include "FolderObject.h" +#include "TodayFolderEdgeObject.h" +#include "TodayFolderObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/FolderEdgeObject.ixx b/samples/today/nointrospection/FolderEdgeObject.ixx index 6a6fdf26..214cb206 100644 --- a/samples/today/nointrospection/FolderEdgeObject.ixx +++ b/samples/today/nointrospection/FolderEdgeObject.ixx @@ -5,7 +5,7 @@ module; -#include "FolderEdgeObject.h" +#include "TodayFolderEdgeObject.h" export module GraphQL.Today.FolderEdgeObject; diff --git a/samples/today/nointrospection/FolderObject.cpp b/samples/today/nointrospection/FolderObject.cpp index 2fc07efd..4b35c950 100644 --- a/samples/today/nointrospection/FolderObject.cpp +++ b/samples/today/nointrospection/FolderObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "FolderObject.h" +#include "TodayFolderObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/FolderObject.ixx b/samples/today/nointrospection/FolderObject.ixx index ca0ee0a7..bd90ad08 100644 --- a/samples/today/nointrospection/FolderObject.ixx +++ b/samples/today/nointrospection/FolderObject.ixx @@ -5,7 +5,7 @@ module; -#include "FolderObject.h" +#include "TodayFolderObject.h" export module GraphQL.Today.FolderObject; diff --git a/samples/today/nointrospection/MutationObject.cpp b/samples/today/nointrospection/MutationObject.cpp index dd7228d1..82232467 100644 --- a/samples/today/nointrospection/MutationObject.cpp +++ b/samples/today/nointrospection/MutationObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "MutationObject.h" -#include "CompleteTaskPayloadObject.h" +#include "TodayMutationObject.h" +#include "TodayCompleteTaskPayloadObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/MutationObject.ixx b/samples/today/nointrospection/MutationObject.ixx index 1f20b3b3..07954b56 100644 --- a/samples/today/nointrospection/MutationObject.ixx +++ b/samples/today/nointrospection/MutationObject.ixx @@ -5,7 +5,7 @@ module; -#include "MutationObject.h" +#include "TodayMutationObject.h" export module GraphQL.Today.MutationObject; diff --git a/samples/today/nointrospection/NestedTypeObject.cpp b/samples/today/nointrospection/NestedTypeObject.cpp index f85ca02c..19fc5677 100644 --- a/samples/today/nointrospection/NestedTypeObject.cpp +++ b/samples/today/nointrospection/NestedTypeObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "NestedTypeObject.h" -#include "NestedTypeObject.h" +#include "TodayNestedTypeObject.h" +#include "TodayNestedTypeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/NestedTypeObject.ixx b/samples/today/nointrospection/NestedTypeObject.ixx index 15db6dc2..514905ed 100644 --- a/samples/today/nointrospection/NestedTypeObject.ixx +++ b/samples/today/nointrospection/NestedTypeObject.ixx @@ -5,7 +5,7 @@ module; -#include "NestedTypeObject.h" +#include "TodayNestedTypeObject.h" export module GraphQL.Today.NestedTypeObject; diff --git a/samples/today/nointrospection/NodeObject.cpp b/samples/today/nointrospection/NodeObject.cpp index 42b73132..924d2996 100644 --- a/samples/today/nointrospection/NodeObject.cpp +++ b/samples/today/nointrospection/NodeObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "NodeObject.h" +#include "TodayNodeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/NodeObject.ixx b/samples/today/nointrospection/NodeObject.ixx index 89446202..af5bfd22 100644 --- a/samples/today/nointrospection/NodeObject.ixx +++ b/samples/today/nointrospection/NodeObject.ixx @@ -5,7 +5,7 @@ module; -#include "NodeObject.h" +#include "TodayNodeObject.h" export module GraphQL.Today.NodeObject; diff --git a/samples/today/nointrospection/PageInfoObject.cpp b/samples/today/nointrospection/PageInfoObject.cpp index 15021499..ea2b05eb 100644 --- a/samples/today/nointrospection/PageInfoObject.cpp +++ b/samples/today/nointrospection/PageInfoObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "PageInfoObject.h" +#include "TodayPageInfoObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/PageInfoObject.ixx b/samples/today/nointrospection/PageInfoObject.ixx index ecb6ce42..2e8855dd 100644 --- a/samples/today/nointrospection/PageInfoObject.ixx +++ b/samples/today/nointrospection/PageInfoObject.ixx @@ -5,7 +5,7 @@ module; -#include "PageInfoObject.h" +#include "TodayPageInfoObject.h" export module GraphQL.Today.PageInfoObject; diff --git a/samples/today/nointrospection/QueryObject.cpp b/samples/today/nointrospection/QueryObject.cpp index f87d63d6..f727c691 100644 --- a/samples/today/nointrospection/QueryObject.cpp +++ b/samples/today/nointrospection/QueryObject.cpp @@ -3,17 +3,17 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "QueryObject.h" -#include "NodeObject.h" -#include "AppointmentConnectionObject.h" -#include "TaskConnectionObject.h" -#include "FolderConnectionObject.h" -#include "AppointmentObject.h" -#include "TaskObject.h" -#include "FolderObject.h" -#include "NestedTypeObject.h" -#include "ExpensiveObject.h" -#include "UnionTypeObject.h" +#include "TodayQueryObject.h" +#include "TodayNodeObject.h" +#include "TodayAppointmentConnectionObject.h" +#include "TodayTaskConnectionObject.h" +#include "TodayFolderConnectionObject.h" +#include "TodayAppointmentObject.h" +#include "TodayTaskObject.h" +#include "TodayFolderObject.h" +#include "TodayNestedTypeObject.h" +#include "TodayExpensiveObject.h" +#include "TodayUnionTypeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/QueryObject.ixx b/samples/today/nointrospection/QueryObject.ixx index 84d3715c..02c0269f 100644 --- a/samples/today/nointrospection/QueryObject.ixx +++ b/samples/today/nointrospection/QueryObject.ixx @@ -5,7 +5,7 @@ module; -#include "QueryObject.h" +#include "TodayQueryObject.h" export module GraphQL.Today.QueryObject; diff --git a/samples/today/nointrospection/SubscriptionObject.cpp b/samples/today/nointrospection/SubscriptionObject.cpp index 16a729fc..f850a9dd 100644 --- a/samples/today/nointrospection/SubscriptionObject.cpp +++ b/samples/today/nointrospection/SubscriptionObject.cpp @@ -3,9 +3,9 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "SubscriptionObject.h" -#include "AppointmentObject.h" -#include "NodeObject.h" +#include "TodaySubscriptionObject.h" +#include "TodayAppointmentObject.h" +#include "TodayNodeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/SubscriptionObject.ixx b/samples/today/nointrospection/SubscriptionObject.ixx index d84fdbd8..2cd09ade 100644 --- a/samples/today/nointrospection/SubscriptionObject.ixx +++ b/samples/today/nointrospection/SubscriptionObject.ixx @@ -5,7 +5,7 @@ module; -#include "SubscriptionObject.h" +#include "TodaySubscriptionObject.h" export module GraphQL.Today.SubscriptionObject; diff --git a/samples/today/nointrospection/TaskConnectionObject.cpp b/samples/today/nointrospection/TaskConnectionObject.cpp index 0950ae4c..060c55ab 100644 --- a/samples/today/nointrospection/TaskConnectionObject.cpp +++ b/samples/today/nointrospection/TaskConnectionObject.cpp @@ -3,9 +3,9 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "TaskConnectionObject.h" -#include "PageInfoObject.h" -#include "TaskEdgeObject.h" +#include "TodayTaskConnectionObject.h" +#include "TodayPageInfoObject.h" +#include "TodayTaskEdgeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/TaskConnectionObject.ixx b/samples/today/nointrospection/TaskConnectionObject.ixx index 8225fa7f..93354afd 100644 --- a/samples/today/nointrospection/TaskConnectionObject.ixx +++ b/samples/today/nointrospection/TaskConnectionObject.ixx @@ -5,7 +5,7 @@ module; -#include "TaskConnectionObject.h" +#include "TodayTaskConnectionObject.h" export module GraphQL.Today.TaskConnectionObject; diff --git a/samples/today/nointrospection/TaskEdgeObject.cpp b/samples/today/nointrospection/TaskEdgeObject.cpp index d48b9bad..37b888da 100644 --- a/samples/today/nointrospection/TaskEdgeObject.cpp +++ b/samples/today/nointrospection/TaskEdgeObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "TaskEdgeObject.h" -#include "TaskObject.h" +#include "TodayTaskEdgeObject.h" +#include "TodayTaskObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/TaskEdgeObject.ixx b/samples/today/nointrospection/TaskEdgeObject.ixx index bdf2bba7..20f2aa47 100644 --- a/samples/today/nointrospection/TaskEdgeObject.ixx +++ b/samples/today/nointrospection/TaskEdgeObject.ixx @@ -5,7 +5,7 @@ module; -#include "TaskEdgeObject.h" +#include "TodayTaskEdgeObject.h" export module GraphQL.Today.TaskEdgeObject; diff --git a/samples/today/nointrospection/TaskObject.cpp b/samples/today/nointrospection/TaskObject.cpp index 8ce3d664..483afb5b 100644 --- a/samples/today/nointrospection/TaskObject.cpp +++ b/samples/today/nointrospection/TaskObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "TaskObject.h" +#include "TodayTaskObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/TaskObject.ixx b/samples/today/nointrospection/TaskObject.ixx index dcf0d814..5fb669e6 100644 --- a/samples/today/nointrospection/TaskObject.ixx +++ b/samples/today/nointrospection/TaskObject.ixx @@ -5,7 +5,7 @@ module; -#include "TaskObject.h" +#include "TodayTaskObject.h" export module GraphQL.Today.TaskObject; diff --git a/samples/today/nointrospection/AppointmentConnectionObject.h b/samples/today/nointrospection/TodayAppointmentConnectionObject.h similarity index 97% rename from samples/today/nointrospection/AppointmentConnectionObject.h rename to samples/today/nointrospection/TodayAppointmentConnectionObject.h index 07f856fc..4640070e 100644 --- a/samples/today/nointrospection/AppointmentConnectionObject.h +++ b/samples/today/nointrospection/TodayAppointmentConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_APPOINTMENTCONNECTIONOBJECT_H -#define TODAY_APPOINTMENTCONNECTIONOBJECT_H +#ifndef TODAY_TODAYAPPOINTMENTCONNECTIONOBJECT_H +#define TODAY_TODAYAPPOINTMENTCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] AppointmentConnection final } // namespace graphql::today::object -#endif // TODAY_APPOINTMENTCONNECTIONOBJECT_H +#endif // TODAY_TODAYAPPOINTMENTCONNECTIONOBJECT_H diff --git a/samples/today/nointrospection/AppointmentEdgeObject.h b/samples/today/nointrospection/TodayAppointmentEdgeObject.h similarity index 97% rename from samples/today/nointrospection/AppointmentEdgeObject.h rename to samples/today/nointrospection/TodayAppointmentEdgeObject.h index 5f5d3c7c..bda2c57f 100644 --- a/samples/today/nointrospection/AppointmentEdgeObject.h +++ b/samples/today/nointrospection/TodayAppointmentEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_APPOINTMENTEDGEOBJECT_H -#define TODAY_APPOINTMENTEDGEOBJECT_H +#ifndef TODAY_TODAYAPPOINTMENTEDGEOBJECT_H +#define TODAY_TODAYAPPOINTMENTEDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] AppointmentEdge final } // namespace graphql::today::object -#endif // TODAY_APPOINTMENTEDGEOBJECT_H +#endif // TODAY_TODAYAPPOINTMENTEDGEOBJECT_H diff --git a/samples/today/nointrospection/AppointmentObject.h b/samples/today/nointrospection/TodayAppointmentObject.h similarity index 98% rename from samples/today/nointrospection/AppointmentObject.h rename to samples/today/nointrospection/TodayAppointmentObject.h index 736e7a60..af90d938 100644 --- a/samples/today/nointrospection/AppointmentObject.h +++ b/samples/today/nointrospection/TodayAppointmentObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_APPOINTMENTOBJECT_H -#define TODAY_APPOINTMENTOBJECT_H +#ifndef TODAY_TODAYAPPOINTMENTOBJECT_H +#define TODAY_TODAYAPPOINTMENTOBJECT_H #include "TodaySchema.h" @@ -266,4 +266,4 @@ class [[nodiscard("unnecessary construction")]] Appointment final } // namespace graphql::today::object -#endif // TODAY_APPOINTMENTOBJECT_H +#endif // TODAY_TODAYAPPOINTMENTOBJECT_H diff --git a/samples/today/schema/CompleteTaskPayloadObject.h b/samples/today/nointrospection/TodayCompleteTaskPayloadObject.h similarity index 97% rename from samples/today/schema/CompleteTaskPayloadObject.h rename to samples/today/nointrospection/TodayCompleteTaskPayloadObject.h index bd85d417..1fd8cb0c 100644 --- a/samples/today/schema/CompleteTaskPayloadObject.h +++ b/samples/today/nointrospection/TodayCompleteTaskPayloadObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_COMPLETETASKPAYLOADOBJECT_H -#define TODAY_COMPLETETASKPAYLOADOBJECT_H +#ifndef TODAY_TODAYCOMPLETETASKPAYLOADOBJECT_H +#define TODAY_TODAYCOMPLETETASKPAYLOADOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] CompleteTaskPayload final } // namespace graphql::today::object -#endif // TODAY_COMPLETETASKPAYLOADOBJECT_H +#endif // TODAY_TODAYCOMPLETETASKPAYLOADOBJECT_H diff --git a/samples/today/schema/ExpensiveObject.h b/samples/today/nointrospection/TodayExpensiveObject.h similarity index 96% rename from samples/today/schema/ExpensiveObject.h rename to samples/today/nointrospection/TodayExpensiveObject.h index 2ad7e18f..6d682efb 100644 --- a/samples/today/schema/ExpensiveObject.h +++ b/samples/today/nointrospection/TodayExpensiveObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_EXPENSIVEOBJECT_H -#define TODAY_EXPENSIVEOBJECT_H +#ifndef TODAY_TODAYEXPENSIVEOBJECT_H +#define TODAY_TODAYEXPENSIVEOBJECT_H #include "TodaySchema.h" @@ -127,4 +127,4 @@ class [[nodiscard("unnecessary construction")]] Expensive final } // namespace graphql::today::object -#endif // TODAY_EXPENSIVEOBJECT_H +#endif // TODAY_TODAYEXPENSIVEOBJECT_H diff --git a/samples/today/schema/FolderConnectionObject.h b/samples/today/nointrospection/TodayFolderConnectionObject.h similarity index 97% rename from samples/today/schema/FolderConnectionObject.h rename to samples/today/nointrospection/TodayFolderConnectionObject.h index 92a5882a..1911fb42 100644 --- a/samples/today/schema/FolderConnectionObject.h +++ b/samples/today/nointrospection/TodayFolderConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_FOLDERCONNECTIONOBJECT_H -#define TODAY_FOLDERCONNECTIONOBJECT_H +#ifndef TODAY_TODAYFOLDERCONNECTIONOBJECT_H +#define TODAY_TODAYFOLDERCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] FolderConnection final } // namespace graphql::today::object -#endif // TODAY_FOLDERCONNECTIONOBJECT_H +#endif // TODAY_TODAYFOLDERCONNECTIONOBJECT_H diff --git a/samples/today/nointrospection/FolderEdgeObject.h b/samples/today/nointrospection/TodayFolderEdgeObject.h similarity index 97% rename from samples/today/nointrospection/FolderEdgeObject.h rename to samples/today/nointrospection/TodayFolderEdgeObject.h index b132f8c1..259c758d 100644 --- a/samples/today/nointrospection/FolderEdgeObject.h +++ b/samples/today/nointrospection/TodayFolderEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_FOLDEREDGEOBJECT_H -#define TODAY_FOLDEREDGEOBJECT_H +#ifndef TODAY_TODAYFOLDEREDGEOBJECT_H +#define TODAY_TODAYFOLDEREDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] FolderEdge final } // namespace graphql::today::object -#endif // TODAY_FOLDEREDGEOBJECT_H +#endif // TODAY_TODAYFOLDEREDGEOBJECT_H diff --git a/samples/today/nointrospection/FolderObject.h b/samples/today/nointrospection/TodayFolderObject.h similarity index 98% rename from samples/today/nointrospection/FolderObject.h rename to samples/today/nointrospection/TodayFolderObject.h index 69312e75..50f9849f 100644 --- a/samples/today/nointrospection/FolderObject.h +++ b/samples/today/nointrospection/TodayFolderObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_FOLDEROBJECT_H -#define TODAY_FOLDEROBJECT_H +#ifndef TODAY_TODAYFOLDEROBJECT_H +#define TODAY_TODAYFOLDEROBJECT_H #include "TodaySchema.h" @@ -206,4 +206,4 @@ class [[nodiscard("unnecessary construction")]] Folder final } // namespace graphql::today::object -#endif // TODAY_FOLDEROBJECT_H +#endif // TODAY_TODAYFOLDEROBJECT_H diff --git a/samples/today/schema/MutationObject.h b/samples/today/nointrospection/TodayMutationObject.h similarity index 97% rename from samples/today/schema/MutationObject.h rename to samples/today/nointrospection/TodayMutationObject.h index b751f79b..13659bd9 100644 --- a/samples/today/schema/MutationObject.h +++ b/samples/today/nointrospection/TodayMutationObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_MUTATIONOBJECT_H -#define TODAY_MUTATIONOBJECT_H +#ifndef TODAY_TODAYMUTATIONOBJECT_H +#define TODAY_TODAYMUTATIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] Mutation final } // namespace graphql::today::object -#endif // TODAY_MUTATIONOBJECT_H +#endif // TODAY_TODAYMUTATIONOBJECT_H diff --git a/samples/today/nointrospection/NestedTypeObject.h b/samples/today/nointrospection/TodayNestedTypeObject.h similarity index 97% rename from samples/today/nointrospection/NestedTypeObject.h rename to samples/today/nointrospection/TodayNestedTypeObject.h index e0d88c9b..aab91089 100644 --- a/samples/today/nointrospection/NestedTypeObject.h +++ b/samples/today/nointrospection/TodayNestedTypeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_NESTEDTYPEOBJECT_H -#define TODAY_NESTEDTYPEOBJECT_H +#ifndef TODAY_TODAYNESTEDTYPEOBJECT_H +#define TODAY_TODAYNESTEDTYPEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] NestedType final } // namespace graphql::today::object -#endif // TODAY_NESTEDTYPEOBJECT_H +#endif // TODAY_TODAYNESTEDTYPEOBJECT_H diff --git a/samples/today/schema/NodeObject.h b/samples/today/nointrospection/TodayNodeObject.h similarity index 95% rename from samples/today/schema/NodeObject.h rename to samples/today/nointrospection/TodayNodeObject.h index 85f82969..a394b40d 100644 --- a/samples/today/schema/NodeObject.h +++ b/samples/today/nointrospection/TodayNodeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_NODEOBJECT_H -#define TODAY_NODEOBJECT_H +#ifndef TODAY_TODAYNODEOBJECT_H +#define TODAY_TODAYNODEOBJECT_H #include "TodaySchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] Node final } // namespace graphql::today::object -#endif // TODAY_NODEOBJECT_H +#endif // TODAY_TODAYNODEOBJECT_H diff --git a/samples/today/schema/PageInfoObject.h b/samples/today/nointrospection/TodayPageInfoObject.h similarity index 97% rename from samples/today/schema/PageInfoObject.h rename to samples/today/nointrospection/TodayPageInfoObject.h index 4b33b8ca..bd63667a 100644 --- a/samples/today/schema/PageInfoObject.h +++ b/samples/today/nointrospection/TodayPageInfoObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_PAGEINFOOBJECT_H -#define TODAY_PAGEINFOOBJECT_H +#ifndef TODAY_TODAYPAGEINFOOBJECT_H +#define TODAY_TODAYPAGEINFOOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] PageInfo final } // namespace graphql::today::object -#endif // TODAY_PAGEINFOOBJECT_H +#endif // TODAY_TODAYPAGEINFOOBJECT_H diff --git a/samples/today/nointrospection/QueryObject.h b/samples/today/nointrospection/TodayQueryObject.h similarity index 99% rename from samples/today/nointrospection/QueryObject.h rename to samples/today/nointrospection/TodayQueryObject.h index ed836819..56799232 100644 --- a/samples/today/nointrospection/QueryObject.h +++ b/samples/today/nointrospection/TodayQueryObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_QUERYOBJECT_H -#define TODAY_QUERYOBJECT_H +#ifndef TODAY_TODAYQUERYOBJECT_H +#define TODAY_TODAYQUERYOBJECT_H #include "TodaySchema.h" @@ -487,4 +487,4 @@ class [[nodiscard("unnecessary construction")]] Query final } // namespace graphql::today::object -#endif // TODAY_QUERYOBJECT_H +#endif // TODAY_TODAYQUERYOBJECT_H diff --git a/samples/today/nointrospection/TodaySchema.cpp b/samples/today/nointrospection/TodaySchema.cpp index 98cf8f6d..fe4ab807 100644 --- a/samples/today/nointrospection/TodaySchema.cpp +++ b/samples/today/nointrospection/TodaySchema.cpp @@ -3,9 +3,9 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "QueryObject.h" -#include "MutationObject.h" -#include "SubscriptionObject.h" +#include "TodayQueryObject.h" +#include "TodayMutationObject.h" +#include "TodaySubscriptionObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/SubscriptionObject.h b/samples/today/nointrospection/TodaySubscriptionObject.h similarity index 97% rename from samples/today/schema/SubscriptionObject.h rename to samples/today/nointrospection/TodaySubscriptionObject.h index c5bef36d..5e21ac98 100644 --- a/samples/today/schema/SubscriptionObject.h +++ b/samples/today/nointrospection/TodaySubscriptionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_SUBSCRIPTIONOBJECT_H -#define TODAY_SUBSCRIPTIONOBJECT_H +#ifndef TODAY_TODAYSUBSCRIPTIONOBJECT_H +#define TODAY_TODAYSUBSCRIPTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] Subscription final } // namespace graphql::today::object -#endif // TODAY_SUBSCRIPTIONOBJECT_H +#endif // TODAY_TODAYSUBSCRIPTIONOBJECT_H diff --git a/samples/today/nointrospection/TaskConnectionObject.h b/samples/today/nointrospection/TodayTaskConnectionObject.h similarity index 97% rename from samples/today/nointrospection/TaskConnectionObject.h rename to samples/today/nointrospection/TodayTaskConnectionObject.h index 2ee84568..46d4153e 100644 --- a/samples/today/nointrospection/TaskConnectionObject.h +++ b/samples/today/nointrospection/TodayTaskConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_TASKCONNECTIONOBJECT_H -#define TODAY_TASKCONNECTIONOBJECT_H +#ifndef TODAY_TODAYTASKCONNECTIONOBJECT_H +#define TODAY_TODAYTASKCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] TaskConnection final } // namespace graphql::today::object -#endif // TODAY_TASKCONNECTIONOBJECT_H +#endif // TODAY_TODAYTASKCONNECTIONOBJECT_H diff --git a/samples/today/schema/TaskEdgeObject.h b/samples/today/nointrospection/TodayTaskEdgeObject.h similarity index 97% rename from samples/today/schema/TaskEdgeObject.h rename to samples/today/nointrospection/TodayTaskEdgeObject.h index 5d57eadf..f4e29482 100644 --- a/samples/today/schema/TaskEdgeObject.h +++ b/samples/today/nointrospection/TodayTaskEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_TASKEDGEOBJECT_H -#define TODAY_TASKEDGEOBJECT_H +#ifndef TODAY_TODAYTASKEDGEOBJECT_H +#define TODAY_TODAYTASKEDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] TaskEdge final } // namespace graphql::today::object -#endif // TODAY_TASKEDGEOBJECT_H +#endif // TODAY_TODAYTASKEDGEOBJECT_H diff --git a/samples/today/nointrospection/TaskObject.h b/samples/today/nointrospection/TodayTaskObject.h similarity index 98% rename from samples/today/nointrospection/TaskObject.h rename to samples/today/nointrospection/TodayTaskObject.h index 6214d27a..d2d31f91 100644 --- a/samples/today/nointrospection/TaskObject.h +++ b/samples/today/nointrospection/TodayTaskObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_TASKOBJECT_H -#define TODAY_TASKOBJECT_H +#ifndef TODAY_TODAYTASKOBJECT_H +#define TODAY_TODAYTASKOBJECT_H #include "TodaySchema.h" @@ -206,4 +206,4 @@ class [[nodiscard("unnecessary construction")]] Task final } // namespace graphql::today::object -#endif // TODAY_TASKOBJECT_H +#endif // TODAY_TODAYTASKOBJECT_H diff --git a/samples/today/nointrospection/UnionTypeObject.h b/samples/today/nointrospection/TodayUnionTypeObject.h similarity index 95% rename from samples/today/nointrospection/UnionTypeObject.h rename to samples/today/nointrospection/TodayUnionTypeObject.h index 0ee56b2b..b99d420d 100644 --- a/samples/today/nointrospection/UnionTypeObject.h +++ b/samples/today/nointrospection/TodayUnionTypeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_UNIONTYPEOBJECT_H -#define TODAY_UNIONTYPEOBJECT_H +#ifndef TODAY_TODAYUNIONTYPEOBJECT_H +#define TODAY_TODAYUNIONTYPEOBJECT_H #include "TodaySchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] UnionType final } // namespace graphql::today::object -#endif // TODAY_UNIONTYPEOBJECT_H +#endif // TODAY_TODAYUNIONTYPEOBJECT_H diff --git a/samples/today/nointrospection/UnionTypeObject.cpp b/samples/today/nointrospection/UnionTypeObject.cpp index 9904e2dc..fe762703 100644 --- a/samples/today/nointrospection/UnionTypeObject.cpp +++ b/samples/today/nointrospection/UnionTypeObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "UnionTypeObject.h" +#include "TodayUnionTypeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/UnionTypeObject.ixx b/samples/today/nointrospection/UnionTypeObject.ixx index bfd588fd..73496d86 100644 --- a/samples/today/nointrospection/UnionTypeObject.ixx +++ b/samples/today/nointrospection/UnionTypeObject.ixx @@ -5,7 +5,7 @@ module; -#include "UnionTypeObject.h" +#include "TodayUnionTypeObject.h" export module GraphQL.Today.UnionTypeObject; diff --git a/samples/today/schema/AppointmentConnectionObject.cpp b/samples/today/schema/AppointmentConnectionObject.cpp index 9ea706b8..ad970e9c 100644 --- a/samples/today/schema/AppointmentConnectionObject.cpp +++ b/samples/today/schema/AppointmentConnectionObject.cpp @@ -3,9 +3,9 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "AppointmentConnectionObject.h" -#include "PageInfoObject.h" -#include "AppointmentEdgeObject.h" +#include "TodayAppointmentConnectionObject.h" +#include "TodayPageInfoObject.h" +#include "TodayAppointmentEdgeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/AppointmentConnectionObject.ixx b/samples/today/schema/AppointmentConnectionObject.ixx index ec982810..3f73da58 100644 --- a/samples/today/schema/AppointmentConnectionObject.ixx +++ b/samples/today/schema/AppointmentConnectionObject.ixx @@ -5,7 +5,7 @@ module; -#include "AppointmentConnectionObject.h" +#include "TodayAppointmentConnectionObject.h" export module GraphQL.Today.AppointmentConnectionObject; diff --git a/samples/today/schema/AppointmentEdgeObject.cpp b/samples/today/schema/AppointmentEdgeObject.cpp index b79f8a66..1aa60cf4 100644 --- a/samples/today/schema/AppointmentEdgeObject.cpp +++ b/samples/today/schema/AppointmentEdgeObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "AppointmentEdgeObject.h" -#include "AppointmentObject.h" +#include "TodayAppointmentEdgeObject.h" +#include "TodayAppointmentObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/AppointmentEdgeObject.ixx b/samples/today/schema/AppointmentEdgeObject.ixx index 8d283bf9..46a48b9e 100644 --- a/samples/today/schema/AppointmentEdgeObject.ixx +++ b/samples/today/schema/AppointmentEdgeObject.ixx @@ -5,7 +5,7 @@ module; -#include "AppointmentEdgeObject.h" +#include "TodayAppointmentEdgeObject.h" export module GraphQL.Today.AppointmentEdgeObject; diff --git a/samples/today/schema/AppointmentObject.cpp b/samples/today/schema/AppointmentObject.cpp index 4ff77df9..39f8910e 100644 --- a/samples/today/schema/AppointmentObject.cpp +++ b/samples/today/schema/AppointmentObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "AppointmentObject.h" +#include "TodayAppointmentObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/AppointmentObject.ixx b/samples/today/schema/AppointmentObject.ixx index 34131b4b..2fc474d8 100644 --- a/samples/today/schema/AppointmentObject.ixx +++ b/samples/today/schema/AppointmentObject.ixx @@ -5,7 +5,7 @@ module; -#include "AppointmentObject.h" +#include "TodayAppointmentObject.h" export module GraphQL.Today.AppointmentObject; diff --git a/samples/today/schema/CMakeLists.txt b/samples/today/schema/CMakeLists.txt index e7e7ee23..2c2dafe1 100644 --- a/samples/today/schema/CMakeLists.txt +++ b/samples/today/schema/CMakeLists.txt @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.28) include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) if(GRAPHQL_UPDATE_SAMPLES) - update_graphql_schema_files(today ../schema.today.graphql Today today --stubs) + update_graphql_schema_files(today ../schema.today.graphql Today today --stubs --prefix-headers) endif() add_graphql_schema_target(today) diff --git a/samples/today/schema/CompleteTaskPayloadObject.cpp b/samples/today/schema/CompleteTaskPayloadObject.cpp index 584a011d..3052500b 100644 --- a/samples/today/schema/CompleteTaskPayloadObject.cpp +++ b/samples/today/schema/CompleteTaskPayloadObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "CompleteTaskPayloadObject.h" -#include "TaskObject.h" +#include "TodayCompleteTaskPayloadObject.h" +#include "TodayTaskObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/CompleteTaskPayloadObject.ixx b/samples/today/schema/CompleteTaskPayloadObject.ixx index fe9415d9..f32cd43c 100644 --- a/samples/today/schema/CompleteTaskPayloadObject.ixx +++ b/samples/today/schema/CompleteTaskPayloadObject.ixx @@ -5,7 +5,7 @@ module; -#include "CompleteTaskPayloadObject.h" +#include "TodayCompleteTaskPayloadObject.h" export module GraphQL.Today.CompleteTaskPayloadObject; diff --git a/samples/today/schema/ExpensiveObject.cpp b/samples/today/schema/ExpensiveObject.cpp index 6c984f82..7c359517 100644 --- a/samples/today/schema/ExpensiveObject.cpp +++ b/samples/today/schema/ExpensiveObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "ExpensiveObject.h" +#include "TodayExpensiveObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/ExpensiveObject.ixx b/samples/today/schema/ExpensiveObject.ixx index 00bf65f4..8cdea947 100644 --- a/samples/today/schema/ExpensiveObject.ixx +++ b/samples/today/schema/ExpensiveObject.ixx @@ -5,7 +5,7 @@ module; -#include "ExpensiveObject.h" +#include "TodayExpensiveObject.h" export module GraphQL.Today.ExpensiveObject; diff --git a/samples/today/schema/FolderConnectionObject.cpp b/samples/today/schema/FolderConnectionObject.cpp index 78fd9094..334dcf14 100644 --- a/samples/today/schema/FolderConnectionObject.cpp +++ b/samples/today/schema/FolderConnectionObject.cpp @@ -3,9 +3,9 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "FolderConnectionObject.h" -#include "PageInfoObject.h" -#include "FolderEdgeObject.h" +#include "TodayFolderConnectionObject.h" +#include "TodayPageInfoObject.h" +#include "TodayFolderEdgeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/FolderConnectionObject.ixx b/samples/today/schema/FolderConnectionObject.ixx index d5434681..1a8e93ea 100644 --- a/samples/today/schema/FolderConnectionObject.ixx +++ b/samples/today/schema/FolderConnectionObject.ixx @@ -5,7 +5,7 @@ module; -#include "FolderConnectionObject.h" +#include "TodayFolderConnectionObject.h" export module GraphQL.Today.FolderConnectionObject; diff --git a/samples/today/schema/FolderEdgeObject.cpp b/samples/today/schema/FolderEdgeObject.cpp index 179e4c37..5e2e341f 100644 --- a/samples/today/schema/FolderEdgeObject.cpp +++ b/samples/today/schema/FolderEdgeObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "FolderEdgeObject.h" -#include "FolderObject.h" +#include "TodayFolderEdgeObject.h" +#include "TodayFolderObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/FolderEdgeObject.ixx b/samples/today/schema/FolderEdgeObject.ixx index 6a6fdf26..214cb206 100644 --- a/samples/today/schema/FolderEdgeObject.ixx +++ b/samples/today/schema/FolderEdgeObject.ixx @@ -5,7 +5,7 @@ module; -#include "FolderEdgeObject.h" +#include "TodayFolderEdgeObject.h" export module GraphQL.Today.FolderEdgeObject; diff --git a/samples/today/schema/FolderObject.cpp b/samples/today/schema/FolderObject.cpp index 2fc07efd..4b35c950 100644 --- a/samples/today/schema/FolderObject.cpp +++ b/samples/today/schema/FolderObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "FolderObject.h" +#include "TodayFolderObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/FolderObject.ixx b/samples/today/schema/FolderObject.ixx index ca0ee0a7..bd90ad08 100644 --- a/samples/today/schema/FolderObject.ixx +++ b/samples/today/schema/FolderObject.ixx @@ -5,7 +5,7 @@ module; -#include "FolderObject.h" +#include "TodayFolderObject.h" export module GraphQL.Today.FolderObject; diff --git a/samples/today/schema/MutationObject.cpp b/samples/today/schema/MutationObject.cpp index dd7228d1..82232467 100644 --- a/samples/today/schema/MutationObject.cpp +++ b/samples/today/schema/MutationObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "MutationObject.h" -#include "CompleteTaskPayloadObject.h" +#include "TodayMutationObject.h" +#include "TodayCompleteTaskPayloadObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/MutationObject.ixx b/samples/today/schema/MutationObject.ixx index 1f20b3b3..07954b56 100644 --- a/samples/today/schema/MutationObject.ixx +++ b/samples/today/schema/MutationObject.ixx @@ -5,7 +5,7 @@ module; -#include "MutationObject.h" +#include "TodayMutationObject.h" export module GraphQL.Today.MutationObject; diff --git a/samples/today/schema/NestedTypeObject.cpp b/samples/today/schema/NestedTypeObject.cpp index fc772276..26043170 100644 --- a/samples/today/schema/NestedTypeObject.cpp +++ b/samples/today/schema/NestedTypeObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "NestedTypeObject.h" -#include "NestedTypeObject.h" +#include "TodayNestedTypeObject.h" +#include "TodayNestedTypeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/NestedTypeObject.ixx b/samples/today/schema/NestedTypeObject.ixx index 15db6dc2..514905ed 100644 --- a/samples/today/schema/NestedTypeObject.ixx +++ b/samples/today/schema/NestedTypeObject.ixx @@ -5,7 +5,7 @@ module; -#include "NestedTypeObject.h" +#include "TodayNestedTypeObject.h" export module GraphQL.Today.NestedTypeObject; diff --git a/samples/today/schema/NodeObject.cpp b/samples/today/schema/NodeObject.cpp index 42b73132..924d2996 100644 --- a/samples/today/schema/NodeObject.cpp +++ b/samples/today/schema/NodeObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "NodeObject.h" +#include "TodayNodeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/NodeObject.ixx b/samples/today/schema/NodeObject.ixx index 89446202..af5bfd22 100644 --- a/samples/today/schema/NodeObject.ixx +++ b/samples/today/schema/NodeObject.ixx @@ -5,7 +5,7 @@ module; -#include "NodeObject.h" +#include "TodayNodeObject.h" export module GraphQL.Today.NodeObject; diff --git a/samples/today/schema/PageInfoObject.cpp b/samples/today/schema/PageInfoObject.cpp index 15021499..ea2b05eb 100644 --- a/samples/today/schema/PageInfoObject.cpp +++ b/samples/today/schema/PageInfoObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "PageInfoObject.h" +#include "TodayPageInfoObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/PageInfoObject.ixx b/samples/today/schema/PageInfoObject.ixx index ecb6ce42..2e8855dd 100644 --- a/samples/today/schema/PageInfoObject.ixx +++ b/samples/today/schema/PageInfoObject.ixx @@ -5,7 +5,7 @@ module; -#include "PageInfoObject.h" +#include "TodayPageInfoObject.h" export module GraphQL.Today.PageInfoObject; diff --git a/samples/today/schema/QueryObject.cpp b/samples/today/schema/QueryObject.cpp index 953af738..64343e99 100644 --- a/samples/today/schema/QueryObject.cpp +++ b/samples/today/schema/QueryObject.cpp @@ -3,17 +3,17 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "QueryObject.h" -#include "NodeObject.h" -#include "AppointmentConnectionObject.h" -#include "TaskConnectionObject.h" -#include "FolderConnectionObject.h" -#include "AppointmentObject.h" -#include "TaskObject.h" -#include "FolderObject.h" -#include "NestedTypeObject.h" -#include "ExpensiveObject.h" -#include "UnionTypeObject.h" +#include "TodayQueryObject.h" +#include "TodayNodeObject.h" +#include "TodayAppointmentConnectionObject.h" +#include "TodayTaskConnectionObject.h" +#include "TodayFolderConnectionObject.h" +#include "TodayAppointmentObject.h" +#include "TodayTaskObject.h" +#include "TodayFolderObject.h" +#include "TodayNestedTypeObject.h" +#include "TodayExpensiveObject.h" +#include "TodayUnionTypeObject.h" #include "graphqlservice/internal/Introspection.h" diff --git a/samples/today/schema/QueryObject.ixx b/samples/today/schema/QueryObject.ixx index 84d3715c..02c0269f 100644 --- a/samples/today/schema/QueryObject.ixx +++ b/samples/today/schema/QueryObject.ixx @@ -5,7 +5,7 @@ module; -#include "QueryObject.h" +#include "TodayQueryObject.h" export module GraphQL.Today.QueryObject; diff --git a/samples/today/schema/SubscriptionObject.cpp b/samples/today/schema/SubscriptionObject.cpp index 16a729fc..f850a9dd 100644 --- a/samples/today/schema/SubscriptionObject.cpp +++ b/samples/today/schema/SubscriptionObject.cpp @@ -3,9 +3,9 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "SubscriptionObject.h" -#include "AppointmentObject.h" -#include "NodeObject.h" +#include "TodaySubscriptionObject.h" +#include "TodayAppointmentObject.h" +#include "TodayNodeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/SubscriptionObject.ixx b/samples/today/schema/SubscriptionObject.ixx index d84fdbd8..2cd09ade 100644 --- a/samples/today/schema/SubscriptionObject.ixx +++ b/samples/today/schema/SubscriptionObject.ixx @@ -5,7 +5,7 @@ module; -#include "SubscriptionObject.h" +#include "TodaySubscriptionObject.h" export module GraphQL.Today.SubscriptionObject; diff --git a/samples/today/schema/TaskConnectionObject.cpp b/samples/today/schema/TaskConnectionObject.cpp index 0950ae4c..060c55ab 100644 --- a/samples/today/schema/TaskConnectionObject.cpp +++ b/samples/today/schema/TaskConnectionObject.cpp @@ -3,9 +3,9 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "TaskConnectionObject.h" -#include "PageInfoObject.h" -#include "TaskEdgeObject.h" +#include "TodayTaskConnectionObject.h" +#include "TodayPageInfoObject.h" +#include "TodayTaskEdgeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/TaskConnectionObject.ixx b/samples/today/schema/TaskConnectionObject.ixx index 8225fa7f..93354afd 100644 --- a/samples/today/schema/TaskConnectionObject.ixx +++ b/samples/today/schema/TaskConnectionObject.ixx @@ -5,7 +5,7 @@ module; -#include "TaskConnectionObject.h" +#include "TodayTaskConnectionObject.h" export module GraphQL.Today.TaskConnectionObject; diff --git a/samples/today/schema/TaskEdgeObject.cpp b/samples/today/schema/TaskEdgeObject.cpp index d48b9bad..37b888da 100644 --- a/samples/today/schema/TaskEdgeObject.cpp +++ b/samples/today/schema/TaskEdgeObject.cpp @@ -3,8 +3,8 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "TaskEdgeObject.h" -#include "TaskObject.h" +#include "TodayTaskEdgeObject.h" +#include "TodayTaskObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/TaskEdgeObject.ixx b/samples/today/schema/TaskEdgeObject.ixx index bdf2bba7..20f2aa47 100644 --- a/samples/today/schema/TaskEdgeObject.ixx +++ b/samples/today/schema/TaskEdgeObject.ixx @@ -5,7 +5,7 @@ module; -#include "TaskEdgeObject.h" +#include "TodayTaskEdgeObject.h" export module GraphQL.Today.TaskEdgeObject; diff --git a/samples/today/schema/TaskObject.cpp b/samples/today/schema/TaskObject.cpp index 8ce3d664..483afb5b 100644 --- a/samples/today/schema/TaskObject.cpp +++ b/samples/today/schema/TaskObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "TaskObject.h" +#include "TodayTaskObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/TaskObject.ixx b/samples/today/schema/TaskObject.ixx index dcf0d814..5fb669e6 100644 --- a/samples/today/schema/TaskObject.ixx +++ b/samples/today/schema/TaskObject.ixx @@ -5,7 +5,7 @@ module; -#include "TaskObject.h" +#include "TodayTaskObject.h" export module GraphQL.Today.TaskObject; diff --git a/samples/today/schema/AppointmentConnectionObject.h b/samples/today/schema/TodayAppointmentConnectionObject.h similarity index 97% rename from samples/today/schema/AppointmentConnectionObject.h rename to samples/today/schema/TodayAppointmentConnectionObject.h index 07f856fc..4640070e 100644 --- a/samples/today/schema/AppointmentConnectionObject.h +++ b/samples/today/schema/TodayAppointmentConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_APPOINTMENTCONNECTIONOBJECT_H -#define TODAY_APPOINTMENTCONNECTIONOBJECT_H +#ifndef TODAY_TODAYAPPOINTMENTCONNECTIONOBJECT_H +#define TODAY_TODAYAPPOINTMENTCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] AppointmentConnection final } // namespace graphql::today::object -#endif // TODAY_APPOINTMENTCONNECTIONOBJECT_H +#endif // TODAY_TODAYAPPOINTMENTCONNECTIONOBJECT_H diff --git a/samples/today/schema/AppointmentEdgeObject.h b/samples/today/schema/TodayAppointmentEdgeObject.h similarity index 97% rename from samples/today/schema/AppointmentEdgeObject.h rename to samples/today/schema/TodayAppointmentEdgeObject.h index 5f5d3c7c..bda2c57f 100644 --- a/samples/today/schema/AppointmentEdgeObject.h +++ b/samples/today/schema/TodayAppointmentEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_APPOINTMENTEDGEOBJECT_H -#define TODAY_APPOINTMENTEDGEOBJECT_H +#ifndef TODAY_TODAYAPPOINTMENTEDGEOBJECT_H +#define TODAY_TODAYAPPOINTMENTEDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] AppointmentEdge final } // namespace graphql::today::object -#endif // TODAY_APPOINTMENTEDGEOBJECT_H +#endif // TODAY_TODAYAPPOINTMENTEDGEOBJECT_H diff --git a/samples/today/schema/AppointmentObject.h b/samples/today/schema/TodayAppointmentObject.h similarity index 98% rename from samples/today/schema/AppointmentObject.h rename to samples/today/schema/TodayAppointmentObject.h index 736e7a60..af90d938 100644 --- a/samples/today/schema/AppointmentObject.h +++ b/samples/today/schema/TodayAppointmentObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_APPOINTMENTOBJECT_H -#define TODAY_APPOINTMENTOBJECT_H +#ifndef TODAY_TODAYAPPOINTMENTOBJECT_H +#define TODAY_TODAYAPPOINTMENTOBJECT_H #include "TodaySchema.h" @@ -266,4 +266,4 @@ class [[nodiscard("unnecessary construction")]] Appointment final } // namespace graphql::today::object -#endif // TODAY_APPOINTMENTOBJECT_H +#endif // TODAY_TODAYAPPOINTMENTOBJECT_H diff --git a/samples/today/nointrospection/CompleteTaskPayloadObject.h b/samples/today/schema/TodayCompleteTaskPayloadObject.h similarity index 97% rename from samples/today/nointrospection/CompleteTaskPayloadObject.h rename to samples/today/schema/TodayCompleteTaskPayloadObject.h index bd85d417..1fd8cb0c 100644 --- a/samples/today/nointrospection/CompleteTaskPayloadObject.h +++ b/samples/today/schema/TodayCompleteTaskPayloadObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_COMPLETETASKPAYLOADOBJECT_H -#define TODAY_COMPLETETASKPAYLOADOBJECT_H +#ifndef TODAY_TODAYCOMPLETETASKPAYLOADOBJECT_H +#define TODAY_TODAYCOMPLETETASKPAYLOADOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] CompleteTaskPayload final } // namespace graphql::today::object -#endif // TODAY_COMPLETETASKPAYLOADOBJECT_H +#endif // TODAY_TODAYCOMPLETETASKPAYLOADOBJECT_H diff --git a/samples/today/nointrospection/ExpensiveObject.h b/samples/today/schema/TodayExpensiveObject.h similarity index 96% rename from samples/today/nointrospection/ExpensiveObject.h rename to samples/today/schema/TodayExpensiveObject.h index 2ad7e18f..6d682efb 100644 --- a/samples/today/nointrospection/ExpensiveObject.h +++ b/samples/today/schema/TodayExpensiveObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_EXPENSIVEOBJECT_H -#define TODAY_EXPENSIVEOBJECT_H +#ifndef TODAY_TODAYEXPENSIVEOBJECT_H +#define TODAY_TODAYEXPENSIVEOBJECT_H #include "TodaySchema.h" @@ -127,4 +127,4 @@ class [[nodiscard("unnecessary construction")]] Expensive final } // namespace graphql::today::object -#endif // TODAY_EXPENSIVEOBJECT_H +#endif // TODAY_TODAYEXPENSIVEOBJECT_H diff --git a/samples/today/nointrospection/FolderConnectionObject.h b/samples/today/schema/TodayFolderConnectionObject.h similarity index 97% rename from samples/today/nointrospection/FolderConnectionObject.h rename to samples/today/schema/TodayFolderConnectionObject.h index 92a5882a..1911fb42 100644 --- a/samples/today/nointrospection/FolderConnectionObject.h +++ b/samples/today/schema/TodayFolderConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_FOLDERCONNECTIONOBJECT_H -#define TODAY_FOLDERCONNECTIONOBJECT_H +#ifndef TODAY_TODAYFOLDERCONNECTIONOBJECT_H +#define TODAY_TODAYFOLDERCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] FolderConnection final } // namespace graphql::today::object -#endif // TODAY_FOLDERCONNECTIONOBJECT_H +#endif // TODAY_TODAYFOLDERCONNECTIONOBJECT_H diff --git a/samples/today/schema/FolderEdgeObject.h b/samples/today/schema/TodayFolderEdgeObject.h similarity index 97% rename from samples/today/schema/FolderEdgeObject.h rename to samples/today/schema/TodayFolderEdgeObject.h index b132f8c1..259c758d 100644 --- a/samples/today/schema/FolderEdgeObject.h +++ b/samples/today/schema/TodayFolderEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_FOLDEREDGEOBJECT_H -#define TODAY_FOLDEREDGEOBJECT_H +#ifndef TODAY_TODAYFOLDEREDGEOBJECT_H +#define TODAY_TODAYFOLDEREDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] FolderEdge final } // namespace graphql::today::object -#endif // TODAY_FOLDEREDGEOBJECT_H +#endif // TODAY_TODAYFOLDEREDGEOBJECT_H diff --git a/samples/today/schema/FolderObject.h b/samples/today/schema/TodayFolderObject.h similarity index 98% rename from samples/today/schema/FolderObject.h rename to samples/today/schema/TodayFolderObject.h index 69312e75..50f9849f 100644 --- a/samples/today/schema/FolderObject.h +++ b/samples/today/schema/TodayFolderObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_FOLDEROBJECT_H -#define TODAY_FOLDEROBJECT_H +#ifndef TODAY_TODAYFOLDEROBJECT_H +#define TODAY_TODAYFOLDEROBJECT_H #include "TodaySchema.h" @@ -206,4 +206,4 @@ class [[nodiscard("unnecessary construction")]] Folder final } // namespace graphql::today::object -#endif // TODAY_FOLDEROBJECT_H +#endif // TODAY_TODAYFOLDEROBJECT_H diff --git a/samples/today/nointrospection/MutationObject.h b/samples/today/schema/TodayMutationObject.h similarity index 97% rename from samples/today/nointrospection/MutationObject.h rename to samples/today/schema/TodayMutationObject.h index b751f79b..13659bd9 100644 --- a/samples/today/nointrospection/MutationObject.h +++ b/samples/today/schema/TodayMutationObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_MUTATIONOBJECT_H -#define TODAY_MUTATIONOBJECT_H +#ifndef TODAY_TODAYMUTATIONOBJECT_H +#define TODAY_TODAYMUTATIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] Mutation final } // namespace graphql::today::object -#endif // TODAY_MUTATIONOBJECT_H +#endif // TODAY_TODAYMUTATIONOBJECT_H diff --git a/samples/today/schema/NestedTypeObject.h b/samples/today/schema/TodayNestedTypeObject.h similarity index 97% rename from samples/today/schema/NestedTypeObject.h rename to samples/today/schema/TodayNestedTypeObject.h index e0d88c9b..aab91089 100644 --- a/samples/today/schema/NestedTypeObject.h +++ b/samples/today/schema/TodayNestedTypeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_NESTEDTYPEOBJECT_H -#define TODAY_NESTEDTYPEOBJECT_H +#ifndef TODAY_TODAYNESTEDTYPEOBJECT_H +#define TODAY_TODAYNESTEDTYPEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] NestedType final } // namespace graphql::today::object -#endif // TODAY_NESTEDTYPEOBJECT_H +#endif // TODAY_TODAYNESTEDTYPEOBJECT_H diff --git a/samples/today/nointrospection/NodeObject.h b/samples/today/schema/TodayNodeObject.h similarity index 95% rename from samples/today/nointrospection/NodeObject.h rename to samples/today/schema/TodayNodeObject.h index 85f82969..a394b40d 100644 --- a/samples/today/nointrospection/NodeObject.h +++ b/samples/today/schema/TodayNodeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_NODEOBJECT_H -#define TODAY_NODEOBJECT_H +#ifndef TODAY_TODAYNODEOBJECT_H +#define TODAY_TODAYNODEOBJECT_H #include "TodaySchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] Node final } // namespace graphql::today::object -#endif // TODAY_NODEOBJECT_H +#endif // TODAY_TODAYNODEOBJECT_H diff --git a/samples/today/nointrospection/PageInfoObject.h b/samples/today/schema/TodayPageInfoObject.h similarity index 97% rename from samples/today/nointrospection/PageInfoObject.h rename to samples/today/schema/TodayPageInfoObject.h index 4b33b8ca..bd63667a 100644 --- a/samples/today/nointrospection/PageInfoObject.h +++ b/samples/today/schema/TodayPageInfoObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_PAGEINFOOBJECT_H -#define TODAY_PAGEINFOOBJECT_H +#ifndef TODAY_TODAYPAGEINFOOBJECT_H +#define TODAY_TODAYPAGEINFOOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] PageInfo final } // namespace graphql::today::object -#endif // TODAY_PAGEINFOOBJECT_H +#endif // TODAY_TODAYPAGEINFOOBJECT_H diff --git a/samples/today/schema/QueryObject.h b/samples/today/schema/TodayQueryObject.h similarity index 99% rename from samples/today/schema/QueryObject.h rename to samples/today/schema/TodayQueryObject.h index 167e1287..c0416c9f 100644 --- a/samples/today/schema/QueryObject.h +++ b/samples/today/schema/TodayQueryObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_QUERYOBJECT_H -#define TODAY_QUERYOBJECT_H +#ifndef TODAY_TODAYQUERYOBJECT_H +#define TODAY_TODAYQUERYOBJECT_H #include "TodaySchema.h" @@ -491,4 +491,4 @@ class [[nodiscard("unnecessary construction")]] Query final } // namespace graphql::today::object -#endif // TODAY_QUERYOBJECT_H +#endif // TODAY_TODAYQUERYOBJECT_H diff --git a/samples/today/schema/TodaySchema.cpp b/samples/today/schema/TodaySchema.cpp index 7436b7fa..c9cadf07 100644 --- a/samples/today/schema/TodaySchema.cpp +++ b/samples/today/schema/TodaySchema.cpp @@ -3,9 +3,9 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "QueryObject.h" -#include "MutationObject.h" -#include "SubscriptionObject.h" +#include "TodayQueryObject.h" +#include "TodayMutationObject.h" +#include "TodaySubscriptionObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/nointrospection/SubscriptionObject.h b/samples/today/schema/TodaySubscriptionObject.h similarity index 97% rename from samples/today/nointrospection/SubscriptionObject.h rename to samples/today/schema/TodaySubscriptionObject.h index c5bef36d..5e21ac98 100644 --- a/samples/today/nointrospection/SubscriptionObject.h +++ b/samples/today/schema/TodaySubscriptionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_SUBSCRIPTIONOBJECT_H -#define TODAY_SUBSCRIPTIONOBJECT_H +#ifndef TODAY_TODAYSUBSCRIPTIONOBJECT_H +#define TODAY_TODAYSUBSCRIPTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] Subscription final } // namespace graphql::today::object -#endif // TODAY_SUBSCRIPTIONOBJECT_H +#endif // TODAY_TODAYSUBSCRIPTIONOBJECT_H diff --git a/samples/today/schema/TaskConnectionObject.h b/samples/today/schema/TodayTaskConnectionObject.h similarity index 97% rename from samples/today/schema/TaskConnectionObject.h rename to samples/today/schema/TodayTaskConnectionObject.h index 2ee84568..46d4153e 100644 --- a/samples/today/schema/TaskConnectionObject.h +++ b/samples/today/schema/TodayTaskConnectionObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_TASKCONNECTIONOBJECT_H -#define TODAY_TASKCONNECTIONOBJECT_H +#ifndef TODAY_TODAYTASKCONNECTIONOBJECT_H +#define TODAY_TODAYTASKCONNECTIONOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] TaskConnection final } // namespace graphql::today::object -#endif // TODAY_TASKCONNECTIONOBJECT_H +#endif // TODAY_TODAYTASKCONNECTIONOBJECT_H diff --git a/samples/today/nointrospection/TaskEdgeObject.h b/samples/today/schema/TodayTaskEdgeObject.h similarity index 97% rename from samples/today/nointrospection/TaskEdgeObject.h rename to samples/today/schema/TodayTaskEdgeObject.h index 5d57eadf..f4e29482 100644 --- a/samples/today/nointrospection/TaskEdgeObject.h +++ b/samples/today/schema/TodayTaskEdgeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_TASKEDGEOBJECT_H -#define TODAY_TASKEDGEOBJECT_H +#ifndef TODAY_TODAYTASKEDGEOBJECT_H +#define TODAY_TODAYTASKEDGEOBJECT_H #include "TodaySchema.h" @@ -157,4 +157,4 @@ class [[nodiscard("unnecessary construction")]] TaskEdge final } // namespace graphql::today::object -#endif // TODAY_TASKEDGEOBJECT_H +#endif // TODAY_TODAYTASKEDGEOBJECT_H diff --git a/samples/today/schema/TaskObject.h b/samples/today/schema/TodayTaskObject.h similarity index 98% rename from samples/today/schema/TaskObject.h rename to samples/today/schema/TodayTaskObject.h index 6214d27a..d2d31f91 100644 --- a/samples/today/schema/TaskObject.h +++ b/samples/today/schema/TodayTaskObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_TASKOBJECT_H -#define TODAY_TASKOBJECT_H +#ifndef TODAY_TODAYTASKOBJECT_H +#define TODAY_TODAYTASKOBJECT_H #include "TodaySchema.h" @@ -206,4 +206,4 @@ class [[nodiscard("unnecessary construction")]] Task final } // namespace graphql::today::object -#endif // TODAY_TASKOBJECT_H +#endif // TODAY_TODAYTASKOBJECT_H diff --git a/samples/today/schema/UnionTypeObject.h b/samples/today/schema/TodayUnionTypeObject.h similarity index 95% rename from samples/today/schema/UnionTypeObject.h rename to samples/today/schema/TodayUnionTypeObject.h index 0ee56b2b..b99d420d 100644 --- a/samples/today/schema/UnionTypeObject.h +++ b/samples/today/schema/TodayUnionTypeObject.h @@ -5,8 +5,8 @@ #pragma once -#ifndef TODAY_UNIONTYPEOBJECT_H -#define TODAY_UNIONTYPEOBJECT_H +#ifndef TODAY_TODAYUNIONTYPEOBJECT_H +#define TODAY_TODAYUNIONTYPEOBJECT_H #include "TodaySchema.h" @@ -78,4 +78,4 @@ class [[nodiscard("unnecessary construction")]] UnionType final } // namespace graphql::today::object -#endif // TODAY_UNIONTYPEOBJECT_H +#endif // TODAY_TODAYUNIONTYPEOBJECT_H diff --git a/samples/today/schema/UnionTypeObject.cpp b/samples/today/schema/UnionTypeObject.cpp index 9904e2dc..fe762703 100644 --- a/samples/today/schema/UnionTypeObject.cpp +++ b/samples/today/schema/UnionTypeObject.cpp @@ -3,7 +3,7 @@ // WARNING! Do not edit this file manually, your changes will be overwritten. -#include "UnionTypeObject.h" +#include "TodayUnionTypeObject.h" #include "graphqlservice/internal/Schema.h" diff --git a/samples/today/schema/UnionTypeObject.ixx b/samples/today/schema/UnionTypeObject.ixx index bfd588fd..73496d86 100644 --- a/samples/today/schema/UnionTypeObject.ixx +++ b/samples/today/schema/UnionTypeObject.ixx @@ -5,7 +5,7 @@ module; -#include "UnionTypeObject.h" +#include "TodayUnionTypeObject.h" export module GraphQL.Today.UnionTypeObject; diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index b3749689..87b17fb5 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -1073,8 +1073,14 @@ void Generator::outputObjectModule( module; -#include ")cpp" << cppType - << R"cpp(Object.h" +#include ")cpp"; + + if (_options.prefixedHeaders) + { + moduleFile << _loader.getFilenamePrefix(); + } + + moduleFile << cppType << R"cpp(Object.h" export module GraphQL.)cpp" << _loader.getFilenamePrefix() << R"cpp(.)cpp" << cppType << R"cpp(Object; @@ -2016,7 +2022,14 @@ bool Generator::outputSchemaSource() const noexcept { for (const auto& operation : _loader.getOperationTypes()) { - sourceFile << R"cpp(#include ")cpp" << operation.cppType << R"cpp(Object.h" + sourceFile << R"cpp(#include ")cpp"; + + if (_options.prefixedHeaders) + { + sourceFile << _loader.getFilenamePrefix(); + } + + sourceFile << operation.cppType << R"cpp(Object.h" )cpp"; } } @@ -3413,7 +3426,9 @@ std::vector Generator::outputSeparateFiles() const noexcept for (const auto& interfaceType : _loader.getInterfaceTypes()) { - const auto headerFilename = std::string(interfaceType.cppType) + "Object.h"; + const auto headerFilename = std::format("{}{}Object.h", + (_options.prefixedHeaders ? _loader.getFilenamePrefix() : std::string_view {}), + interfaceType.cppType); auto headerPath = (headerDir / headerFilename).string(); { @@ -3498,7 +3513,9 @@ using namespace std::literals; for (const auto& unionType : _loader.getUnionTypes()) { - const auto headerFilename = std::string(unionType.cppType) + "Object.h"; + const auto headerFilename = std::format("{}{}Object.h", + (_options.prefixedHeaders ? _loader.getFilenamePrefix() : std::string_view {}), + unionType.cppType); auto headerPath = (headerDir / headerFilename).string(); { @@ -3603,7 +3620,9 @@ using namespace std::literals; } } - const auto headerFilename = std::string(objectType.cppType) + "Object.h"; + const auto headerFilename = std::format("{}{}Object.h", + (_options.prefixedHeaders ? _loader.getFilenamePrefix() : std::string_view {}), + objectType.cppType); auto headerPath = (headerDir / headerFilename).string(); { @@ -3686,8 +3705,14 @@ using namespace std::literals; case OutputFieldType::Object: if (includedObjects.insert(field.type).second) { - sourceFile << R"cpp(#include ")cpp" - << SchemaLoader::getSafeCppName(field.type) + sourceFile << R"cpp(#include ")cpp"; + + if (_options.prefixedHeaders) + { + sourceFile << _loader.getFilenamePrefix(); + } + + sourceFile << SchemaLoader::getSafeCppName(field.type) << R"cpp(Object.h" )cpp"; } @@ -3788,6 +3813,7 @@ int main(int argc, char** argv) bool verbose = false; bool stubs = false; bool noIntrospection = false; + bool prefixedHeaders = false; std::string schemaFileName; std::string filenamePrefix; std::string schemaNamespace; @@ -3814,7 +3840,9 @@ int main(int argc, char** argv) "Unimplemented fields throw runtime exceptions instead of compiler errors")("no-" "introspection", po::bool_switch(&noIntrospection), - "Do not generate support for Introspection"); + "Do not generate support for Introspection")("prefix-headers", + po::bool_switch(&prefixedHeaders), + "Prefix generated object header filenames"); positional.add("schema", 1).add("prefix", 1).add("namespace", 1); internalOptions.add_options()("introspection", po::bool_switch(&buildIntrospection), @@ -3879,6 +3907,7 @@ int main(int argc, char** argv) verbose, // verbose stubs, // stubs noIntrospection, // noIntrospection + prefixedHeaders, // prefixedHeaders }) .Build(); From b53247c060678e4dee012b8d699dd02859e09e43 Mon Sep 17 00:00:00 2001 From: rafalh Date: Wed, 6 Nov 2024 12:31:05 +0100 Subject: [PATCH 110/123] Add enum value validation --- src/SchemaGenerator.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 87b17fb5..5c3fb8cd 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -1691,8 +1691,15 @@ service::AwaitableResolver Result<)cpp" []()cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType << R"cpp( value, const ResolverParams&) { + const size_t idx = static_cast(value); + if (idx >= s_names)cpp" + << enumType.cppType << R"cpp(.size()) + { + throw service::schema_exception { { R"ex(Enum value out of range for )cpp" + << enumType.type << R"cpp()ex" } }; + } return ResolverResult { { response::ValueToken::EnumValue { std::string { s_names)cpp" - << enumType.cppType << R"cpp([static_cast(value)] } } } }; + << enumType.cppType << R"cpp([idx] } } } }; }); } From bd85564031641415db1597381f07cc7f7002b653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Hibner?= Date: Thu, 21 Nov 2024 11:09:42 +0100 Subject: [PATCH 111/123] Trigger conversion error --- samples/today/schema.today.graphql | 1 + test/ClientTests.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/today/schema.today.graphql b/samples/today/schema.today.graphql index 8c794450..94e9770a 100644 --- a/samples/today/schema.today.graphql +++ b/samples/today/schema.today.graphql @@ -87,6 +87,7 @@ input CompleteTaskInput { testTaskState: TaskState isComplete: Boolean = true clientMutationId: String + boolList: [Boolean!] } type CompleteTaskPayload { diff --git a/test/ClientTests.cpp b/test/ClientTests.cpp index 26a1bcb9..4f674d00 100644 --- a/test/ClientTests.cpp +++ b/test/ClientTests.cpp @@ -246,7 +246,8 @@ TEST_F(ClientCase, MutateCompleteTask) { std::make_unique(CompleteTaskInput { today::getFakeTaskId(), std::nullopt, std::make_optional(true), - std::make_optional("Hi There!"s) }) }); + std::make_optional("Hi There!"s), + std::vector({true,false}) }) }); auto state = std::make_shared(5); auto result = From f7cfbc5ab2db1fa56c7dc7eadab3d55ed23f34c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Hibner?= Date: Thu, 21 Nov 2024 13:42:33 +0000 Subject: [PATCH 112/123] Update generated files --- samples/client/multiple/MultipleQueriesClient.cpp | 9 ++++++++- samples/client/multiple/MultipleQueriesClient.h | 4 +++- samples/client/mutate/MutateClient.cpp | 9 ++++++++- samples/client/mutate/MutateClient.h | 4 +++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/samples/client/multiple/MultipleQueriesClient.cpp b/samples/client/multiple/MultipleQueriesClient.cpp index 1644ddcb..177380a0 100644 --- a/samples/client/multiple/MultipleQueriesClient.cpp +++ b/samples/client/multiple/MultipleQueriesClient.cpp @@ -131,6 +131,7 @@ CompleteTaskInput::CompleteTaskInput() noexcept , testTaskState {} , isComplete {} , clientMutationId {} + , boolList {} { // Explicit definition to prevent ODR violations when LTO is enabled. } @@ -139,11 +140,13 @@ CompleteTaskInput::CompleteTaskInput( response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept : id { std::move(idArg) } , testTaskState { std::move(testTaskStateArg) } , isComplete { std::move(isCompleteArg) } , clientMutationId { std::move(clientMutationIdArg) } + , boolList { std::move(boolListArg) } { } @@ -152,6 +155,7 @@ CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) , testTaskState { ModifiedVariable::duplicate(other.testTaskState) } , isComplete { ModifiedVariable::duplicate(other.isComplete) } , clientMutationId { ModifiedVariable::duplicate(other.clientMutationId) } + , boolList { ModifiedVariable::duplicate(other.boolList) } { } @@ -160,6 +164,7 @@ CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept , testTaskState { std::move(other.testTaskState) } , isComplete { std::move(other.isComplete) } , clientMutationId { std::move(other.clientMutationId) } + , boolList { std::move(other.boolList) } { } @@ -179,6 +184,7 @@ CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexc testTaskState = std::move(other.testTaskState); isComplete = std::move(other.isComplete); clientMutationId = std::move(other.clientMutationId); + boolList = std::move(other.boolList); return *this; } @@ -2316,6 +2322,7 @@ response::Value Variable::serialize(CompleteTaskInput&& input result.emplace_back(R"js(testTaskState)js"s, ModifiedVariable::serialize(std::move(inputValue.testTaskState))); result.emplace_back(R"js(isComplete)js"s, ModifiedVariable::serialize(std::move(inputValue.isComplete))); result.emplace_back(R"js(clientMutationId)js"s, ModifiedVariable::serialize(std::move(inputValue.clientMutationId))); + result.emplace_back(R"js(boolList)js"s, ModifiedVariable::serialize(std::move(inputValue.boolList))); return result; } diff --git a/samples/client/multiple/MultipleQueriesClient.h b/samples/client/multiple/MultipleQueriesClient.h index 4e711034..a7c7460e 100644 --- a/samples/client/multiple/MultipleQueriesClient.h +++ b/samples/client/multiple/MultipleQueriesClient.h @@ -132,7 +132,8 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept; + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept; CompleteTaskInput(const CompleteTaskInput& other); CompleteTaskInput(CompleteTaskInput&& other) noexcept; ~CompleteTaskInput(); @@ -144,6 +145,7 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput std::optional testTaskState; std::optional isComplete; std::optional clientMutationId; + std::optional> boolList; }; namespace client { diff --git a/samples/client/mutate/MutateClient.cpp b/samples/client/mutate/MutateClient.cpp index f54db298..248b86a8 100644 --- a/samples/client/mutate/MutateClient.cpp +++ b/samples/client/mutate/MutateClient.cpp @@ -64,6 +64,7 @@ CompleteTaskInput::CompleteTaskInput() noexcept , testTaskState {} , isComplete {} , clientMutationId {} + , boolList {} { // Explicit definition to prevent ODR violations when LTO is enabled. } @@ -72,11 +73,13 @@ CompleteTaskInput::CompleteTaskInput( response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept : id { std::move(idArg) } , testTaskState { std::move(testTaskStateArg) } , isComplete { std::move(isCompleteArg) } , clientMutationId { std::move(clientMutationIdArg) } + , boolList { std::move(boolListArg) } { } @@ -85,6 +88,7 @@ CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) , testTaskState { ModifiedVariable::duplicate(other.testTaskState) } , isComplete { ModifiedVariable::duplicate(other.isComplete) } , clientMutationId { ModifiedVariable::duplicate(other.clientMutationId) } + , boolList { ModifiedVariable::duplicate(other.boolList) } { } @@ -93,6 +97,7 @@ CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept , testTaskState { std::move(other.testTaskState) } , isComplete { std::move(other.isComplete) } , clientMutationId { std::move(other.clientMutationId) } + , boolList { std::move(other.boolList) } { } @@ -112,6 +117,7 @@ CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexc testTaskState = std::move(other.testTaskState); isComplete = std::move(other.isComplete); clientMutationId = std::move(other.clientMutationId); + boolList = std::move(other.boolList); return *this; } @@ -148,6 +154,7 @@ response::Value Variable::serialize(CompleteTaskInput&& input result.emplace_back(R"js(testTaskState)js"s, ModifiedVariable::serialize(std::move(inputValue.testTaskState))); result.emplace_back(R"js(isComplete)js"s, ModifiedVariable::serialize(std::move(inputValue.isComplete))); result.emplace_back(R"js(clientMutationId)js"s, ModifiedVariable::serialize(std::move(inputValue.clientMutationId))); + result.emplace_back(R"js(boolList)js"s, ModifiedVariable::serialize(std::move(inputValue.boolList))); return result; } diff --git a/samples/client/mutate/MutateClient.h b/samples/client/mutate/MutateClient.h index 4c945b24..72a67a45 100644 --- a/samples/client/mutate/MutateClient.h +++ b/samples/client/mutate/MutateClient.h @@ -65,7 +65,8 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept; + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept; CompleteTaskInput(const CompleteTaskInput& other); CompleteTaskInput(CompleteTaskInput&& other) noexcept; ~CompleteTaskInput(); @@ -77,6 +78,7 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput std::optional testTaskState; std::optional isComplete; std::optional clientMutationId; + std::optional> boolList; }; namespace client { From 523d16f6c4d15315657d2a20e3941612e40c03f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Hibner?= Date: Tue, 19 Nov 2024 13:54:39 +0000 Subject: [PATCH 113/123] Fix list of boolean argument --- include/graphqlservice/GraphQLClient.h | 31 ++++++++++++++++++------- include/graphqlservice/GraphQLService.h | 18 ++++++++++---- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index a1f5b5d7..13ce6cdf 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -168,9 +168,16 @@ struct ModifiedVariable response::Value result { response::Type::List }; result.reserve(listValue.size()); - std::ranges::for_each(listValue, [&result](auto& value) { - result.emplace_back(serialize(std::move(value))); - }); + if constexpr(std::is_same_v){ + for (auto const v: listValue) + result.emplace_back(Variable::serialize(bool{v})); + } + else{ + std::ranges::for_each(listValue, [&result](auto& value) { + result.emplace_back(serialize(std::move(value))); + }); + } + listValue.clear(); return result; @@ -217,11 +224,19 @@ struct ModifiedVariable duplicate(const typename VariableTraits::type& listValue) requires ListModifier { - typename VariableTraits::type result(listValue.size()); - - std::ranges::transform(listValue, result.begin(), duplicate); - - return result; + if constexpr(std::is_same_v){ + typename VariableTraits::type result; + result.reserve(listValue.size()); + for (auto const v: listValue) + result.push_back(v); + return result; + } + else + { + typename VariableTraits::type result(listValue.size()); + std::ranges::transform(listValue, result.begin(), duplicate); + return result; + } } }; diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index b6c6eac2..dacf9ce5 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -795,11 +795,19 @@ struct ModifiedArgument duplicate(const typename ArgumentTraits::type& listValue) requires ListModifier { - typename ArgumentTraits::type result(listValue.size()); - - std::ranges::transform(listValue, result.begin(), duplicate); - - return result; + if constexpr(std::is_same_v){ + typename ArgumentTraits::type result; + result.reserve(listValue.size()); + for (auto const v: listValue) + result.push_back(v); + return result; + } + else + { + typename ArgumentTraits::type result(listValue.size()); + std::ranges::transform(listValue, result.begin(), duplicate); + return result; + } } }; From e48538f83b57622b90e306a6f2ca1436d90098a1 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 7 Dec 2024 14:45:59 -0800 Subject: [PATCH 114/123] chore: regenerate samples with enum validation --- samples/learn/schema/StarWarsSharedTypes.cpp | 9 ++++++++- samples/proxy/schema/ProxySharedTypes.cpp | 9 ++++++++- .../today/nointrospection/TodaySharedTypes.cpp | 9 ++++++++- samples/today/schema/TodaySharedTypes.cpp | 9 ++++++++- .../schema/ValidationSharedTypes.cpp | 18 ++++++++++++++++-- src/SchemaGenerator.cpp | 2 ++ src/introspection/IntrospectionSharedTypes.cpp | 18 ++++++++++++++++-- 7 files changed, 66 insertions(+), 8 deletions(-) diff --git a/samples/learn/schema/StarWarsSharedTypes.cpp b/samples/learn/schema/StarWarsSharedTypes.cpp index b1034fe2..48fcf3a9 100644 --- a/samples/learn/schema/StarWarsSharedTypes.cpp +++ b/samples/learn/schema/StarWarsSharedTypes.cpp @@ -50,7 +50,14 @@ service::AwaitableResolver Result::convert(service::AwaitableSca return ModifiedResult::resolve(std::move(result), std::move(params), [](learn::Episode value, const ResolverParams&) { - return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesEpisode[static_cast(value)] } } } }; + const size_t idx = static_cast(value); + + if (idx >= s_namesEpisode.size()) + { + throw service::schema_exception { { R"ex(Enum value out of range for Episode)ex" } }; + } + + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesEpisode[idx] } } } }; }); } diff --git a/samples/proxy/schema/ProxySharedTypes.cpp b/samples/proxy/schema/ProxySharedTypes.cpp index 8fba4aa3..d58c8f99 100644 --- a/samples/proxy/schema/ProxySharedTypes.cpp +++ b/samples/proxy/schema/ProxySharedTypes.cpp @@ -50,7 +50,14 @@ service::AwaitableResolver Result::convert(service::Awaita return ModifiedResult::resolve(std::move(result), std::move(params), [](proxy::OperationType value, const ResolverParams&) { - return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesOperationType[static_cast(value)] } } } }; + const size_t idx = static_cast(value); + + if (idx >= s_namesOperationType.size()) + { + throw service::schema_exception { { R"ex(Enum value out of range for OperationType)ex" } }; + } + + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesOperationType[idx] } } } }; }); } diff --git a/samples/today/nointrospection/TodaySharedTypes.cpp b/samples/today/nointrospection/TodaySharedTypes.cpp index 2d9d50ca..727a3253 100644 --- a/samples/today/nointrospection/TodaySharedTypes.cpp +++ b/samples/today/nointrospection/TodaySharedTypes.cpp @@ -50,7 +50,14 @@ service::AwaitableResolver Result::convert(service::AwaitableS return ModifiedResult::resolve(std::move(result), std::move(params), [](today::TaskState value, const ResolverParams&) { - return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesTaskState[static_cast(value)] } } } }; + const size_t idx = static_cast(value); + + if (idx >= s_namesTaskState.size()) + { + throw service::schema_exception { { R"ex(Enum value out of range for TaskState)ex" } }; + } + + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesTaskState[idx] } } } }; }); } diff --git a/samples/today/schema/TodaySharedTypes.cpp b/samples/today/schema/TodaySharedTypes.cpp index 2d9d50ca..727a3253 100644 --- a/samples/today/schema/TodaySharedTypes.cpp +++ b/samples/today/schema/TodaySharedTypes.cpp @@ -50,7 +50,14 @@ service::AwaitableResolver Result::convert(service::AwaitableS return ModifiedResult::resolve(std::move(result), std::move(params), [](today::TaskState value, const ResolverParams&) { - return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesTaskState[static_cast(value)] } } } }; + const size_t idx = static_cast(value); + + if (idx >= s_namesTaskState.size()) + { + throw service::schema_exception { { R"ex(Enum value out of range for TaskState)ex" } }; + } + + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesTaskState[idx] } } } }; }); } diff --git a/samples/validation/schema/ValidationSharedTypes.cpp b/samples/validation/schema/ValidationSharedTypes.cpp index 4db548fa..84e32700 100644 --- a/samples/validation/schema/ValidationSharedTypes.cpp +++ b/samples/validation/schema/ValidationSharedTypes.cpp @@ -50,7 +50,14 @@ service::AwaitableResolver Result::convert(service::Awai return ModifiedResult::resolve(std::move(result), std::move(params), [](validation::DogCommand value, const ResolverParams&) { - return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesDogCommand[static_cast(value)] } } } }; + const size_t idx = static_cast(value); + + if (idx >= s_namesDogCommand.size()) + { + throw service::schema_exception { { R"ex(Enum value out of range for DogCommand)ex" } }; + } + + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesDogCommand[idx] } } } }; }); } @@ -102,7 +109,14 @@ service::AwaitableResolver Result::convert(service::Awai return ModifiedResult::resolve(std::move(result), std::move(params), [](validation::CatCommand value, const ResolverParams&) { - return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesCatCommand[static_cast(value)] } } } }; + const size_t idx = static_cast(value); + + if (idx >= s_namesCatCommand.size()) + { + throw service::schema_exception { { R"ex(Enum value out of range for CatCommand)ex" } }; + } + + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesCatCommand[idx] } } } }; }); } diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 5c3fb8cd..1a0351d4 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -1692,12 +1692,14 @@ service::AwaitableResolver Result<)cpp" << R"cpp(::)cpp" << enumType.cppType << R"cpp( value, const ResolverParams&) { const size_t idx = static_cast(value); + if (idx >= s_names)cpp" << enumType.cppType << R"cpp(.size()) { throw service::schema_exception { { R"ex(Enum value out of range for )cpp" << enumType.type << R"cpp()ex" } }; } + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_names)cpp" << enumType.cppType << R"cpp([idx] } } } }; }); diff --git a/src/introspection/IntrospectionSharedTypes.cpp b/src/introspection/IntrospectionSharedTypes.cpp index ba9a3e7e..7d47c719 100644 --- a/src/introspection/IntrospectionSharedTypes.cpp +++ b/src/introspection/IntrospectionSharedTypes.cpp @@ -50,7 +50,14 @@ service::AwaitableResolver Result::convert(service::Awa return ModifiedResult::resolve(std::move(result), std::move(params), [](introspection::TypeKind value, const ResolverParams&) { - return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesTypeKind[static_cast(value)] } } } }; + const size_t idx = static_cast(value); + + if (idx >= s_namesTypeKind.size()) + { + throw service::schema_exception { { R"ex(Enum value out of range for __TypeKind)ex" } }; + } + + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesTypeKind[idx] } } } }; }); } @@ -102,7 +109,14 @@ service::AwaitableResolver Result::convert(ser return ModifiedResult::resolve(std::move(result), std::move(params), [](introspection::DirectiveLocation value, const ResolverParams&) { - return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesDirectiveLocation[static_cast(value)] } } } }; + const size_t idx = static_cast(value); + + if (idx >= s_namesDirectiveLocation.size()) + { + throw service::schema_exception { { R"ex(Enum value out of range for __DirectiveLocation)ex" } }; + } + + return ResolverResult { { response::ValueToken::EnumValue { std::string { s_namesDirectiveLocation[idx] } } } }; }); } From 364311641105d6805eaa826e629e113229d155d6 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 7 Dec 2024 16:21:31 -0800 Subject: [PATCH 115/123] fix(merge): regenerate samples after merge --- samples/learn/schema/StarWarsSharedTypes.cpp | 2 +- samples/proxy/schema/ProxySharedTypes.cpp | 2 +- samples/today/nointrospection/TodaySharedTypes.cpp | 2 +- samples/today/schema/TodaySharedTypes.cpp | 2 +- samples/validation/schema/ValidationSharedTypes.cpp | 4 ++-- src/introspection/IntrospectionSharedTypes.cpp | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/samples/learn/schema/StarWarsSharedTypes.cpp b/samples/learn/schema/StarWarsSharedTypes.cpp index 48fcf3a9..697d2181 100644 --- a/samples/learn/schema/StarWarsSharedTypes.cpp +++ b/samples/learn/schema/StarWarsSharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::AwaitableSca return ModifiedResult::resolve(std::move(result), std::move(params), [](learn::Episode value, const ResolverParams&) { - const size_t idx = static_cast(value); + const auto idx = static_cast(value); if (idx >= s_namesEpisode.size()) { diff --git a/samples/proxy/schema/ProxySharedTypes.cpp b/samples/proxy/schema/ProxySharedTypes.cpp index d58c8f99..e29d62da 100644 --- a/samples/proxy/schema/ProxySharedTypes.cpp +++ b/samples/proxy/schema/ProxySharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::Awaita return ModifiedResult::resolve(std::move(result), std::move(params), [](proxy::OperationType value, const ResolverParams&) { - const size_t idx = static_cast(value); + const auto idx = static_cast(value); if (idx >= s_namesOperationType.size()) { diff --git a/samples/today/nointrospection/TodaySharedTypes.cpp b/samples/today/nointrospection/TodaySharedTypes.cpp index 727a3253..f733934a 100644 --- a/samples/today/nointrospection/TodaySharedTypes.cpp +++ b/samples/today/nointrospection/TodaySharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::AwaitableS return ModifiedResult::resolve(std::move(result), std::move(params), [](today::TaskState value, const ResolverParams&) { - const size_t idx = static_cast(value); + const auto idx = static_cast(value); if (idx >= s_namesTaskState.size()) { diff --git a/samples/today/schema/TodaySharedTypes.cpp b/samples/today/schema/TodaySharedTypes.cpp index 727a3253..f733934a 100644 --- a/samples/today/schema/TodaySharedTypes.cpp +++ b/samples/today/schema/TodaySharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::AwaitableS return ModifiedResult::resolve(std::move(result), std::move(params), [](today::TaskState value, const ResolverParams&) { - const size_t idx = static_cast(value); + const auto idx = static_cast(value); if (idx >= s_namesTaskState.size()) { diff --git a/samples/validation/schema/ValidationSharedTypes.cpp b/samples/validation/schema/ValidationSharedTypes.cpp index 84e32700..aa67bdbb 100644 --- a/samples/validation/schema/ValidationSharedTypes.cpp +++ b/samples/validation/schema/ValidationSharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::Awai return ModifiedResult::resolve(std::move(result), std::move(params), [](validation::DogCommand value, const ResolverParams&) { - const size_t idx = static_cast(value); + const auto idx = static_cast(value); if (idx >= s_namesDogCommand.size()) { @@ -109,7 +109,7 @@ service::AwaitableResolver Result::convert(service::Awai return ModifiedResult::resolve(std::move(result), std::move(params), [](validation::CatCommand value, const ResolverParams&) { - const size_t idx = static_cast(value); + const auto idx = static_cast(value); if (idx >= s_namesCatCommand.size()) { diff --git a/src/introspection/IntrospectionSharedTypes.cpp b/src/introspection/IntrospectionSharedTypes.cpp index 7d47c719..9457eec6 100644 --- a/src/introspection/IntrospectionSharedTypes.cpp +++ b/src/introspection/IntrospectionSharedTypes.cpp @@ -50,7 +50,7 @@ service::AwaitableResolver Result::convert(service::Awa return ModifiedResult::resolve(std::move(result), std::move(params), [](introspection::TypeKind value, const ResolverParams&) { - const size_t idx = static_cast(value); + const auto idx = static_cast(value); if (idx >= s_namesTypeKind.size()) { @@ -109,7 +109,7 @@ service::AwaitableResolver Result::convert(ser return ModifiedResult::resolve(std::move(result), std::move(params), [](introspection::DirectiveLocation value, const ResolverParams&) { - const size_t idx = static_cast(value); + const auto idx = static_cast(value); if (idx >= s_namesDirectiveLocation.size()) { From 29ccf43a826e2626978f5ae14911185ec17b4770 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 7 Dec 2024 16:53:56 -0800 Subject: [PATCH 116/123] fix: handle potential modifiers on bool lists --- include/graphqlservice/GraphQLClient.h | 30 ++++++++++--------- include/graphqlservice/GraphQLService.h | 15 +++++----- samples/today/nointrospection/TodaySchema.cpp | 3 +- .../nointrospection/TodaySharedTypes.cpp | 12 ++++++-- .../today/nointrospection/TodaySharedTypes.h | 4 ++- samples/today/schema/TodaySchema.cpp | 3 +- samples/today/schema/TodaySharedTypes.cpp | 12 ++++++-- samples/today/schema/TodaySharedTypes.h | 4 ++- 8 files changed, 53 insertions(+), 30 deletions(-) diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index 13ce6cdf..8db4830e 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -168,16 +168,19 @@ struct ModifiedVariable response::Value result { response::Type::List }; result.reserve(listValue.size()); - if constexpr(std::is_same_v){ - for (auto const v: listValue) - result.emplace_back(Variable::serialize(bool{v})); + if constexpr (std::is_same_v && OnlyNoneModifiers) + { + std::ranges::for_each(listValue, [&result](bool value) { + result.emplace_back(response::Value { value }); + }); } - else{ + else + { std::ranges::for_each(listValue, [&result](auto& value) { result.emplace_back(serialize(std::move(value))); - }); + }); } - + listValue.clear(); return result; @@ -224,19 +227,18 @@ struct ModifiedVariable duplicate(const typename VariableTraits::type& listValue) requires ListModifier { - if constexpr(std::is_same_v){ - typename VariableTraits::type result; - result.reserve(listValue.size()); - for (auto const v: listValue) - result.push_back(v); - return result; + typename VariableTraits::type result(listValue.size()); + + if constexpr (std::is_same_v && OnlyNoneModifiers) + { + std::copy(listValue.begin(), listValue.end(), result.begin()); } else { - typename VariableTraits::type result(listValue.size()); std::ranges::transform(listValue, result.begin(), duplicate); - return result; } + + return result; } }; diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index dacf9ce5..5c5f11f6 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -795,19 +795,18 @@ struct ModifiedArgument duplicate(const typename ArgumentTraits::type& listValue) requires ListModifier { - if constexpr(std::is_same_v){ - typename ArgumentTraits::type result; - result.reserve(listValue.size()); - for (auto const v: listValue) - result.push_back(v); - return result; + typename ArgumentTraits::type result(listValue.size()); + + if constexpr (std::is_same_v && OnlyNoneModifiers) + { + std::copy(listValue.begin(), listValue.end(), result.begin()); } else { - typename ArgumentTraits::type result(listValue.size()); std::ranges::transform(listValue, result.begin(), duplicate); - return result; } + + return result; } }; diff --git a/samples/today/nointrospection/TodaySchema.cpp b/samples/today/nointrospection/TodaySchema.cpp index fe4ab807..f8a4d23c 100644 --- a/samples/today/nointrospection/TodaySchema.cpp +++ b/samples/today/nointrospection/TodaySchema.cpp @@ -109,7 +109,8 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema::InputValue::Make(R"gql(id)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)), R"gql()gql"sv), schema::InputValue::Make(R"gql(testTaskState)gql"sv, R"md()md"sv, schema->LookupType(R"gql(TaskState)gql"sv), R"gql()gql"sv), schema::InputValue::Make(R"gql(isComplete)gql"sv, R"md()md"sv, schema->LookupType(R"gql(Boolean)gql"sv), R"gql(true)gql"sv), - schema::InputValue::Make(R"gql(clientMutationId)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql()gql"sv) + schema::InputValue::Make(R"gql(clientMutationId)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql()gql"sv), + schema::InputValue::Make(R"gql(boolList)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::LIST, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(Boolean)gql"sv))), R"gql()gql"sv) }); typeThirdNestedInput->AddInputValues({ schema::InputValue::Make(R"gql(id)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)), R"gql()gql"sv), diff --git a/samples/today/nointrospection/TodaySharedTypes.cpp b/samples/today/nointrospection/TodaySharedTypes.cpp index f733934a..ecae70c3 100644 --- a/samples/today/nointrospection/TodaySharedTypes.cpp +++ b/samples/today/nointrospection/TodaySharedTypes.cpp @@ -101,12 +101,14 @@ today::CompleteTaskInput Argument::convert(const respo ? std::move(pairIsComplete.first) : service::ModifiedArgument::require("isComplete", defaultValue)); auto valueClientMutationId = service::ModifiedArgument::require("clientMutationId", value); + auto valueBoolList = service::ModifiedArgument::require("boolList", value); return today::CompleteTaskInput { std::move(valueId), valueTestTaskState, std::move(valueIsComplete), - std::move(valueClientMutationId) + std::move(valueClientMutationId), + std::move(valueBoolList) }; } @@ -231,6 +233,7 @@ CompleteTaskInput::CompleteTaskInput() noexcept , testTaskState {} , isComplete {} , clientMutationId {} + , boolList {} { // Explicit definition to prevent ODR violations when LTO is enabled. } @@ -239,11 +242,13 @@ CompleteTaskInput::CompleteTaskInput( response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept : id { std::move(idArg) } , testTaskState { std::move(testTaskStateArg) } , isComplete { std::move(isCompleteArg) } , clientMutationId { std::move(clientMutationIdArg) } + , boolList { std::move(boolListArg) } { } @@ -252,6 +257,7 @@ CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) , testTaskState { service::ModifiedArgument::duplicate(other.testTaskState) } , isComplete { service::ModifiedArgument::duplicate(other.isComplete) } , clientMutationId { service::ModifiedArgument::duplicate(other.clientMutationId) } + , boolList { service::ModifiedArgument::duplicate(other.boolList) } { } @@ -260,6 +266,7 @@ CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept , testTaskState { std::move(other.testTaskState) } , isComplete { std::move(other.isComplete) } , clientMutationId { std::move(other.clientMutationId) } + , boolList { std::move(other.boolList) } { } @@ -283,6 +290,7 @@ CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexc testTaskState = std::move(other.testTaskState); isComplete = std::move(other.isComplete); clientMutationId = std::move(other.clientMutationId); + boolList = std::move(other.boolList); return *this; } diff --git a/samples/today/nointrospection/TodaySharedTypes.h b/samples/today/nointrospection/TodaySharedTypes.h index b3c7b086..a9f1ace9 100644 --- a/samples/today/nointrospection/TodaySharedTypes.h +++ b/samples/today/nointrospection/TodaySharedTypes.h @@ -65,7 +65,8 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept; + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept; CompleteTaskInput(const CompleteTaskInput& other); CompleteTaskInput(CompleteTaskInput&& other) noexcept; ~CompleteTaskInput(); @@ -77,6 +78,7 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput std::optional testTaskState; std::optional isComplete; std::optional clientMutationId; + std::optional> boolList; }; struct SecondNestedInput; diff --git a/samples/today/schema/TodaySchema.cpp b/samples/today/schema/TodaySchema.cpp index c9cadf07..831e7bbf 100644 --- a/samples/today/schema/TodaySchema.cpp +++ b/samples/today/schema/TodaySchema.cpp @@ -112,7 +112,8 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema::InputValue::Make(R"gql(id)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)), R"gql()gql"sv), schema::InputValue::Make(R"gql(testTaskState)gql"sv, R"md()md"sv, schema->LookupType(R"gql(TaskState)gql"sv), R"gql()gql"sv), schema::InputValue::Make(R"gql(isComplete)gql"sv, R"md()md"sv, schema->LookupType(R"gql(Boolean)gql"sv), R"gql(true)gql"sv), - schema::InputValue::Make(R"gql(clientMutationId)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql()gql"sv) + schema::InputValue::Make(R"gql(clientMutationId)gql"sv, R"md()md"sv, schema->LookupType(R"gql(String)gql"sv), R"gql()gql"sv), + schema::InputValue::Make(R"gql(boolList)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::LIST, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(Boolean)gql"sv))), R"gql()gql"sv) }); typeThirdNestedInput->AddInputValues({ schema::InputValue::Make(R"gql(id)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)), R"gql()gql"sv), diff --git a/samples/today/schema/TodaySharedTypes.cpp b/samples/today/schema/TodaySharedTypes.cpp index f733934a..ecae70c3 100644 --- a/samples/today/schema/TodaySharedTypes.cpp +++ b/samples/today/schema/TodaySharedTypes.cpp @@ -101,12 +101,14 @@ today::CompleteTaskInput Argument::convert(const respo ? std::move(pairIsComplete.first) : service::ModifiedArgument::require("isComplete", defaultValue)); auto valueClientMutationId = service::ModifiedArgument::require("clientMutationId", value); + auto valueBoolList = service::ModifiedArgument::require("boolList", value); return today::CompleteTaskInput { std::move(valueId), valueTestTaskState, std::move(valueIsComplete), - std::move(valueClientMutationId) + std::move(valueClientMutationId), + std::move(valueBoolList) }; } @@ -231,6 +233,7 @@ CompleteTaskInput::CompleteTaskInput() noexcept , testTaskState {} , isComplete {} , clientMutationId {} + , boolList {} { // Explicit definition to prevent ODR violations when LTO is enabled. } @@ -239,11 +242,13 @@ CompleteTaskInput::CompleteTaskInput( response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept : id { std::move(idArg) } , testTaskState { std::move(testTaskStateArg) } , isComplete { std::move(isCompleteArg) } , clientMutationId { std::move(clientMutationIdArg) } + , boolList { std::move(boolListArg) } { } @@ -252,6 +257,7 @@ CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) , testTaskState { service::ModifiedArgument::duplicate(other.testTaskState) } , isComplete { service::ModifiedArgument::duplicate(other.isComplete) } , clientMutationId { service::ModifiedArgument::duplicate(other.clientMutationId) } + , boolList { service::ModifiedArgument::duplicate(other.boolList) } { } @@ -260,6 +266,7 @@ CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept , testTaskState { std::move(other.testTaskState) } , isComplete { std::move(other.isComplete) } , clientMutationId { std::move(other.clientMutationId) } + , boolList { std::move(other.boolList) } { } @@ -283,6 +290,7 @@ CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexc testTaskState = std::move(other.testTaskState); isComplete = std::move(other.isComplete); clientMutationId = std::move(other.clientMutationId); + boolList = std::move(other.boolList); return *this; } diff --git a/samples/today/schema/TodaySharedTypes.h b/samples/today/schema/TodaySharedTypes.h index b3c7b086..a9f1ace9 100644 --- a/samples/today/schema/TodaySharedTypes.h +++ b/samples/today/schema/TodaySharedTypes.h @@ -65,7 +65,8 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept; + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept; CompleteTaskInput(const CompleteTaskInput& other); CompleteTaskInput(CompleteTaskInput&& other) noexcept; ~CompleteTaskInput(); @@ -77,6 +78,7 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput std::optional testTaskState; std::optional isComplete; std::optional clientMutationId; + std::optional> boolList; }; struct SecondNestedInput; From 876b0cb1c5c2b043905ae58f584bd1a5a5f96fab Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 2 Nov 2024 13:00:06 -0700 Subject: [PATCH 117/123] chore(deps): update PEGTL sub-module to 3.2.8 --- PEGTL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PEGTL b/PEGTL index cf639f7f..be527327 160000 --- a/PEGTL +++ b/PEGTL @@ -1 +1 @@ -Subproject commit cf639f7f4ee125f68e1ccfba8d99ebc0de57b9fe +Subproject commit be527327653e94b02e711f7eff59285ad13e1db0 From 10d1124824b3369ee5194eaa7fa0700d3d5d5343 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sat, 2 Nov 2024 13:32:16 -0700 Subject: [PATCH 118/123] fix(build): build today and stitched samples without modules --- samples/CMakeLists.txt | 11 +---- samples/today/CMakeLists.txt | 90 ++++++++++++++++++------------------ 2 files changed, 48 insertions(+), 53 deletions(-) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index b3d479d7..9b86c5af 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -3,17 +3,10 @@ cmake_minimum_required(VERSION 3.28) -if(GRAPHQL_BUILD_MODULES) - add_subdirectory(today) -endif() - +add_subdirectory(today) add_subdirectory(client) add_subdirectory(learn) - -if(GRAPHQL_BUILD_MODULES) - add_subdirectory(stitched) -endif() - +add_subdirectory(stitched) add_subdirectory(validation) if(GRAPHQL_BUILD_HTTP_SAMPLE) diff --git a/samples/today/CMakeLists.txt b/samples/today/CMakeLists.txt index 9b6e1a6e..1ed024a7 100644 --- a/samples/today/CMakeLists.txt +++ b/samples/today/CMakeLists.txt @@ -37,49 +37,51 @@ if(MSVC) target_compile_options(todaygraphql_nointrospection PUBLIC /wd4702) endif() -# sample -add_executable(sample sample.cpp) -target_link_libraries(sample PRIVATE - todaygraphql - graphqljson) - -# sample_nointrospection -add_executable(sample_nointrospection sample.cpp) -target_link_libraries(sample_nointrospection PRIVATE - todaygraphql_nointrospection - graphqljson) - -# benchmark -add_executable(benchmark benchmark.cpp) -target_link_libraries(benchmark PRIVATE - todaygraphql - graphqljson) - -# benchmark_nointrospection -add_executable(benchmark_nointrospection benchmark.cpp) -target_link_libraries(benchmark_nointrospection PRIVATE - todaygraphql_nointrospection - graphqljson) - -if(WIN32 AND BUILD_SHARED_LIBS) - add_custom_command(OUTPUT copied_sample_dlls - COMMAND ${CMAKE_COMMAND} -E copy_if_different - $ - $ - $ - $ - ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E touch copied_sample_dlls - DEPENDS - graphqlservice - graphqljson - graphqlpeg - graphqlresponse) - - add_custom_target(copy_today_sample_dlls DEPENDS copied_sample_dlls) +if(GRAPHQL_BUILD_MODULES) + # sample + add_executable(sample sample.cpp) + target_link_libraries(sample PRIVATE + todaygraphql + graphqljson) - add_dependencies(sample copy_today_sample_dlls) - add_dependencies(sample_nointrospection copy_today_sample_dlls) - add_dependencies(benchmark copy_today_sample_dlls) - add_dependencies(benchmark_nointrospection copy_today_sample_dlls) + # sample_nointrospection + add_executable(sample_nointrospection sample.cpp) + target_link_libraries(sample_nointrospection PRIVATE + todaygraphql_nointrospection + graphqljson) + + # benchmark + add_executable(benchmark benchmark.cpp) + target_link_libraries(benchmark PRIVATE + todaygraphql + graphqljson) + + # benchmark_nointrospection + add_executable(benchmark_nointrospection benchmark.cpp) + target_link_libraries(benchmark_nointrospection PRIVATE + todaygraphql_nointrospection + graphqljson) + + if(WIN32 AND BUILD_SHARED_LIBS) + add_custom_command(OUTPUT copied_sample_dlls + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + $ + $ + $ + ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E touch copied_sample_dlls + DEPENDS + graphqlservice + graphqljson + graphqlpeg + graphqlresponse) + + add_custom_target(copy_today_sample_dlls DEPENDS copied_sample_dlls) + + add_dependencies(sample copy_today_sample_dlls) + add_dependencies(sample_nointrospection copy_today_sample_dlls) + add_dependencies(benchmark copy_today_sample_dlls) + add_dependencies(benchmark_nointrospection copy_today_sample_dlls) + endif() endif() From 8e0aa147f7e62f1335c1f646349a3059061db547 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 8 Dec 2024 20:21:44 -0800 Subject: [PATCH 119/123] fix: #338 --- samples/client/query/QueryClient.cpp | 33 +++++++++++++++ samples/client/query/QueryClient.h | 2 + samples/client/query/query.today.graphql | 1 + samples/proxy/query/ProxyClient.cpp | 5 --- .../nointrospection/AppointmentObject.cpp | 15 ++++++- .../nointrospection/TodayAppointmentObject.h | 30 +++++++++++++ samples/today/schema.today.graphql | 1 + samples/today/schema/AppointmentObject.cpp | 15 ++++++- samples/today/schema/TodayAppointmentObject.h | 30 +++++++++++++ src/ClientGenerator.cpp | 42 +++++-------------- 10 files changed, 136 insertions(+), 38 deletions(-) diff --git a/samples/client/query/QueryClient.cpp b/samples/client/query/QueryClient.cpp index e6d9d180..934d4593 100644 --- a/samples/client/query/QueryClient.cpp +++ b/samples/client/query/QueryClient.cpp @@ -78,6 +78,7 @@ const std::string& GetRequestText() noexcept subject when isNow + array } } @@ -431,6 +432,11 @@ graphql::query::client::query::Query::Response::anyType_UnionType Response::parse(std::move(member.second)); continue; } + if (member.first == R"js(array)js"sv) + { + result.array = ModifiedResponse::parse(std::move(member.second)); + continue; + } } } @@ -492,6 +498,9 @@ struct ResponseVisitor::impl Member_anyType_0_subject, Member_anyType_0_when, Member_anyType_0_isNow, + Member_anyType_0_array, + Member_anyType_0_array_0, + Member_anyType_0_array_0_, Member_default_, Complete, }; @@ -666,6 +675,10 @@ void ResponseVisitor::add_value([[maybe_unused]] std::shared_ptrresponse.anyType.back()->isNow = ModifiedResponse::parse(response::Value { *value }); break; + case impl::VisitorState::Member_anyType_0_array_0: + _pimpl->response.anyType.back()->array.push_back(ModifiedResponse::parse(response::Value { *value })); + break; + case impl::VisitorState::Member_default_: _pimpl->state = impl::VisitorState::Start; _pimpl->response.default_ = ModifiedResponse::parse(response::Value { *value }); @@ -699,6 +712,10 @@ void ResponseVisitor::reserve([[maybe_unused]] std::size_t count) _pimpl->response.anyType.reserve(count); break; + case impl::VisitorState::Member_anyType_0_array_0: + _pimpl->response.anyType.back()->array.reserve(count); + break; + case impl::VisitorState::Complete: break; @@ -914,6 +931,10 @@ void ResponseVisitor::add_member([[maybe_unused]] std::string&& key) { _pimpl->state = impl::VisitorState::Member_anyType_0_isNow; } + else if (key == "array"sv) + { + _pimpl->state = impl::VisitorState::Member_anyType_0_array; + } break; case impl::VisitorState::Complete: @@ -999,6 +1020,10 @@ void ResponseVisitor::start_array() _pimpl->state = impl::VisitorState::Member_anyType_0; break; + case impl::VisitorState::Member_anyType_0_array: + _pimpl->state = impl::VisitorState::Member_anyType_0_array_0; + break; + case impl::VisitorState::Complete: break; @@ -1027,6 +1052,10 @@ void ResponseVisitor::end_array() _pimpl->state = impl::VisitorState::Start; break; + case impl::VisitorState::Member_anyType_0_array_0: + _pimpl->state = impl::VisitorState::Member_anyType_0_; + break; + case impl::VisitorState::Complete: break; @@ -1226,6 +1255,10 @@ void ResponseVisitor::add_id([[maybe_unused]] response::IdType&& value) _pimpl->response.anyType.back()->id = std::move(value); break; + case impl::VisitorState::Member_anyType_0_array_0: + _pimpl->response.anyType.back()->array.push_back(std::move(value)); + break; + case impl::VisitorState::Complete: break; diff --git a/samples/client/query/QueryClient.h b/samples/client/query/QueryClient.h index 9f52a969..36f7798e 100644 --- a/samples/client/query/QueryClient.h +++ b/samples/client/query/QueryClient.h @@ -81,6 +81,7 @@ namespace graphql::query { /// subject /// when /// isNow +/// array /// } /// } /// @@ -184,6 +185,7 @@ struct [[nodiscard("unnecessary construction")]] Response std::optional subject {}; std::optional when {}; bool isNow {}; + std::vector array {}; }; appointments_AppointmentConnection appointments {}; diff --git a/samples/client/query/query.today.graphql b/samples/client/query/query.today.graphql index 56bef0a3..32217e9c 100644 --- a/samples/client/query/query.today.graphql +++ b/samples/client/query/query.today.graphql @@ -53,6 +53,7 @@ query { subject when isNow + array } } diff --git a/samples/proxy/query/ProxyClient.cpp b/samples/proxy/query/ProxyClient.cpp index 8a8362d8..14d71d52 100644 --- a/samples/proxy/query/ProxyClient.cpp +++ b/samples/proxy/query/ProxyClient.cpp @@ -236,11 +236,6 @@ void ResponseVisitor::start_object() { switch (_pimpl->state) { - case impl::VisitorState::Member_relay_errors_0: - _pimpl->state = impl::VisitorState::Member_relay_errors_0_; - _pimpl->response.relay.errors->push_back(std::make_optional({})); - break; - case impl::VisitorState::Complete: break; diff --git a/samples/today/nointrospection/AppointmentObject.cpp b/samples/today/nointrospection/AppointmentObject.cpp index 39f8910e..ada849cd 100644 --- a/samples/today/nointrospection/AppointmentObject.cpp +++ b/samples/today/nointrospection/AppointmentObject.cpp @@ -39,6 +39,7 @@ service::ResolverMap Appointment::getResolvers() const noexcept return { { R"gql(id)gql"sv, [this](service::ResolverParams&& params) { return resolveId(std::move(params)); } }, { R"gql(when)gql"sv, [this](service::ResolverParams&& params) { return resolveWhen(std::move(params)); } }, + { R"gql(array)gql"sv, [this](service::ResolverParams&& params) { return resolveArray(std::move(params)); } }, { R"gql(isNow)gql"sv, [this](service::ResolverParams&& params) { return resolveIsNow(std::move(params)); } }, { R"gql(subject)gql"sv, [this](service::ResolverParams&& params) { return resolveSubject(std::move(params)); } }, { R"gql(__typename)gql"sv, [this](service::ResolverParams&& params) { return resolve_typename(std::move(params)); } }, @@ -111,6 +112,17 @@ service::AwaitableResolver Appointment::resolveForceError(service::ResolverParam return service::ModifiedResult::convert(std::move(result), std::move(params)); } +service::AwaitableResolver Appointment::resolveArray(service::ResolverParams&& params) const +{ + std::unique_lock resolverLock(_resolverMutex); + service::SelectionSetParams selectionSetParams { static_cast(params) }; + auto directives = std::move(params.fieldDirectives); + auto result = _pimpl->getArray(service::FieldParams { std::move(selectionSetParams), std::move(directives) }); + resolverLock.unlock(); + + return service::ModifiedResult::convert(std::move(result), std::move(params)); +} + service::AwaitableResolver Appointment::resolve_typename(service::ResolverParams&& params) const { return service::Result::convert(std::string{ R"gql(Appointment)gql" }, std::move(params)); @@ -128,7 +140,8 @@ void AddAppointmentDetails(const std::shared_ptr& typeAppoin schema::Field::Make(R"gql(when)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(DateTime)gql"sv)), schema::Field::Make(R"gql(subject)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv)), schema::Field::Make(R"gql(isNow)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(Boolean)gql"sv))), - schema::Field::Make(R"gql(forceError)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv)) + schema::Field::Make(R"gql(forceError)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv)), + schema::Field::Make(R"gql(array)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->WrapType(introspection::TypeKind::LIST, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv))))) }); } diff --git a/samples/today/nointrospection/TodayAppointmentObject.h b/samples/today/nointrospection/TodayAppointmentObject.h index af90d938..7507a086 100644 --- a/samples/today/nointrospection/TodayAppointmentObject.h +++ b/samples/today/nointrospection/TodayAppointmentObject.h @@ -80,6 +80,18 @@ concept getForceError = requires (TImpl impl) { service::AwaitableScalar> { impl.getForceError() } }; }; +template +concept getArrayWithParams = requires (TImpl impl, service::FieldParams params) +{ + { service::AwaitableScalar> { impl.getArray(std::move(params)) } }; +}; + +template +concept getArray = requires (TImpl impl) +{ + { service::AwaitableScalar> { impl.getArray() } }; +}; + template concept beginSelectionSet = requires (TImpl impl, const service::SelectionSetParams params) { @@ -103,6 +115,7 @@ class [[nodiscard("unnecessary construction")]] Appointment final [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveSubject(service::ResolverParams&& params) const; [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveIsNow(service::ResolverParams&& params) const; [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveForceError(service::ResolverParams&& params) const; + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveArray(service::ResolverParams&& params) const; [[nodiscard("unnecessary call")]] service::AwaitableResolver resolve_typename(service::ResolverParams&& params) const; @@ -118,6 +131,7 @@ class [[nodiscard("unnecessary construction")]] Appointment final [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar> getSubject(service::FieldParams&& params) const = 0; [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar getIsNow(service::FieldParams&& params) const = 0; [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar> getForceError(service::FieldParams&& params) const = 0; + [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar> getArray(service::FieldParams&& params) const = 0; }; template @@ -209,6 +223,22 @@ class [[nodiscard("unnecessary construction")]] Appointment final } } + [[nodiscard("unnecessary call")]] service::AwaitableScalar> getArray(service::FieldParams&& params) const override + { + if constexpr (methods::AppointmentHas::getArrayWithParams) + { + return { _pimpl->getArray(std::move(params)) }; + } + else if constexpr (methods::AppointmentHas::getArray) + { + return { _pimpl->getArray() }; + } + else + { + throw service::unimplemented_method(R"ex(Appointment::getArray)ex"); + } + } + void beginSelectionSet(const service::SelectionSetParams& params) const override { if constexpr (methods::AppointmentHas::beginSelectionSet) diff --git a/samples/today/schema.today.graphql b/samples/today/schema.today.graphql index 94e9770a..59b77ae9 100644 --- a/samples/today/schema.today.graphql +++ b/samples/today/schema.today.graphql @@ -132,6 +132,7 @@ type Appointment implements Node { subject: String isNow: Boolean! forceError: String + array: [ID!]! } type Task implements Node { diff --git a/samples/today/schema/AppointmentObject.cpp b/samples/today/schema/AppointmentObject.cpp index 39f8910e..ada849cd 100644 --- a/samples/today/schema/AppointmentObject.cpp +++ b/samples/today/schema/AppointmentObject.cpp @@ -39,6 +39,7 @@ service::ResolverMap Appointment::getResolvers() const noexcept return { { R"gql(id)gql"sv, [this](service::ResolverParams&& params) { return resolveId(std::move(params)); } }, { R"gql(when)gql"sv, [this](service::ResolverParams&& params) { return resolveWhen(std::move(params)); } }, + { R"gql(array)gql"sv, [this](service::ResolverParams&& params) { return resolveArray(std::move(params)); } }, { R"gql(isNow)gql"sv, [this](service::ResolverParams&& params) { return resolveIsNow(std::move(params)); } }, { R"gql(subject)gql"sv, [this](service::ResolverParams&& params) { return resolveSubject(std::move(params)); } }, { R"gql(__typename)gql"sv, [this](service::ResolverParams&& params) { return resolve_typename(std::move(params)); } }, @@ -111,6 +112,17 @@ service::AwaitableResolver Appointment::resolveForceError(service::ResolverParam return service::ModifiedResult::convert(std::move(result), std::move(params)); } +service::AwaitableResolver Appointment::resolveArray(service::ResolverParams&& params) const +{ + std::unique_lock resolverLock(_resolverMutex); + service::SelectionSetParams selectionSetParams { static_cast(params) }; + auto directives = std::move(params.fieldDirectives); + auto result = _pimpl->getArray(service::FieldParams { std::move(selectionSetParams), std::move(directives) }); + resolverLock.unlock(); + + return service::ModifiedResult::convert(std::move(result), std::move(params)); +} + service::AwaitableResolver Appointment::resolve_typename(service::ResolverParams&& params) const { return service::Result::convert(std::string{ R"gql(Appointment)gql" }, std::move(params)); @@ -128,7 +140,8 @@ void AddAppointmentDetails(const std::shared_ptr& typeAppoin schema::Field::Make(R"gql(when)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(DateTime)gql"sv)), schema::Field::Make(R"gql(subject)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv)), schema::Field::Make(R"gql(isNow)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(Boolean)gql"sv))), - schema::Field::Make(R"gql(forceError)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv)) + schema::Field::Make(R"gql(forceError)gql"sv, R"md()md"sv, std::nullopt, schema->LookupType(R"gql(String)gql"sv)), + schema::Field::Make(R"gql(array)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->WrapType(introspection::TypeKind::LIST, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv))))) }); } diff --git a/samples/today/schema/TodayAppointmentObject.h b/samples/today/schema/TodayAppointmentObject.h index af90d938..7507a086 100644 --- a/samples/today/schema/TodayAppointmentObject.h +++ b/samples/today/schema/TodayAppointmentObject.h @@ -80,6 +80,18 @@ concept getForceError = requires (TImpl impl) { service::AwaitableScalar> { impl.getForceError() } }; }; +template +concept getArrayWithParams = requires (TImpl impl, service::FieldParams params) +{ + { service::AwaitableScalar> { impl.getArray(std::move(params)) } }; +}; + +template +concept getArray = requires (TImpl impl) +{ + { service::AwaitableScalar> { impl.getArray() } }; +}; + template concept beginSelectionSet = requires (TImpl impl, const service::SelectionSetParams params) { @@ -103,6 +115,7 @@ class [[nodiscard("unnecessary construction")]] Appointment final [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveSubject(service::ResolverParams&& params) const; [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveIsNow(service::ResolverParams&& params) const; [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveForceError(service::ResolverParams&& params) const; + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveArray(service::ResolverParams&& params) const; [[nodiscard("unnecessary call")]] service::AwaitableResolver resolve_typename(service::ResolverParams&& params) const; @@ -118,6 +131,7 @@ class [[nodiscard("unnecessary construction")]] Appointment final [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar> getSubject(service::FieldParams&& params) const = 0; [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar getIsNow(service::FieldParams&& params) const = 0; [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar> getForceError(service::FieldParams&& params) const = 0; + [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar> getArray(service::FieldParams&& params) const = 0; }; template @@ -209,6 +223,22 @@ class [[nodiscard("unnecessary construction")]] Appointment final } } + [[nodiscard("unnecessary call")]] service::AwaitableScalar> getArray(service::FieldParams&& params) const override + { + if constexpr (methods::AppointmentHas::getArrayWithParams) + { + return { _pimpl->getArray(std::move(params)) }; + } + else if constexpr (methods::AppointmentHas::getArray) + { + return { _pimpl->getArray() }; + } + else + { + throw service::unimplemented_method(R"ex(Appointment::getArray)ex"); + } + } + void beginSelectionSet(const service::SelectionSetParams& params) const override { if constexpr (methods::AppointmentHas::beginSelectionSet) diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 6f3de4a9..857e892e 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -2203,6 +2203,11 @@ void Generator::outputResponseFieldVisitorReserve(std::ostream& sourceFile, } } + if (dereference) + { + accessor.append(R"cpp(.)cpp"); + } + std::unordered_set fieldNames; switch (responseField.type->kind()) @@ -2211,37 +2216,6 @@ void Generator::outputResponseFieldVisitorReserve(std::ostream& sourceFile, case introspection::TypeKind::INTERFACE: case introspection::TypeKind::UNION: { - dereference = true; - - for (auto modifier : responseField.modifiers) - { - switch (modifier) - { - case service::TypeModifier::None: - break; - - case service::TypeModifier::Nullable: - accessor.append(R"cpp(->)cpp"); - dereference = false; - break; - - case service::TypeModifier::List: - if (dereference) - { - accessor.append(R"cpp(.)cpp"); - } - - accessor.append(R"cpp(back())cpp"); - dereference = true; - break; - } - } - - if (dereference) - { - accessor.append(R"cpp(.)cpp"); - } - for (const auto& field : responseField.children) { if (fieldNames.emplace(field.name).second) @@ -2263,6 +2237,12 @@ void Generator::outputResponseFieldVisitorStartObject(std::ostream& sourceFile, std::string_view parentAccessor /* = {} */, std::string_view parentCppType /* = {} */) const noexcept { + if (responseField.type->kind() == introspection::TypeKind::SCALAR + && SchemaLoader::getBuiltinTypes().contains(responseField.type->name())) + { + return; + } + auto state = std::format("{}_{}", parentState.empty() ? R"cpp(Member)cpp"sv : parentState, responseField.cppName); From 9bf6d475fa1b32f8a53dce4e7e58aaf2c47981e8 Mon Sep 17 00:00:00 2001 From: Bill Avery Date: Sun, 8 Dec 2024 20:29:52 -0800 Subject: [PATCH 120/123] fix: update test for new sample field --- samples/today/TodayMock.cpp | 5 +++++ samples/today/TodayMock.h | 1 + 2 files changed, 6 insertions(+) diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index 62d06c50..c05834d7 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -186,6 +186,11 @@ std::optional Appointment::getForceError() const throw std::runtime_error(R"ex(this error was forced)ex"); } +std::vector Appointment::getArray() const +{ + return {}; +} + AppointmentEdge::AppointmentEdge(std::shared_ptr appointment) : _appointment(std::move(appointment)) { diff --git a/samples/today/TodayMock.h b/samples/today/TodayMock.h index 3ccf15b1..6709cba9 100644 --- a/samples/today/TodayMock.h +++ b/samples/today/TodayMock.h @@ -146,6 +146,7 @@ class Appointment std::shared_ptr getSubject() const noexcept; bool getIsNow() const noexcept; std::optional getForceError() const; + std::vector getArray() const; private: response::IdType _id; From db4bd3262798f6079728d78712d3688719a0de77 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Sep 2026 21:44:17 +0000 Subject: [PATCH 121/123] Initial plan From 6fb11bb9757fa52030c5ddc4f65aa357678d074a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Sep 2026 22:08:19 +0000 Subject: [PATCH 122/123] Add @cppType directive for custom scalar C++ types (fixes #346) Co-authored-by: wravery <6502881+wravery@users.noreply.github.com> --- README.md | 1 + doc/directives.md | 9 +- doc/scalars.md | 122 ++++++++++++++ include/SchemaLoader.h | 13 ++ include/graphqlservice/GraphQLService.h | 14 +- samples/CMakeLists.txt | 1 + samples/scalar/BigIntScalar.cpp | 75 +++++++++ samples/scalar/BigIntScalar.h | 69 ++++++++ samples/scalar/CMakeLists.txt | 14 ++ samples/scalar/schema.scalar.graphql | 24 +++ samples/scalar/schema/CMakeLists.txt | 23 +++ samples/scalar/schema/QueryObject.cpp | 134 +++++++++++++++ samples/scalar/schema/QueryObject.h | 194 ++++++++++++++++++++++ samples/scalar/schema/ScalarSchema.cpp | 62 +++++++ samples/scalar/schema/ScalarSchema.h | 57 +++++++ samples/scalar/schema/scalar_schema_files | 2 + src/SchemaGenerator.cpp | 27 ++- src/SchemaLoader.cpp | 42 ++++- test/CMakeLists.txt | 10 ++ test/ScalarTests.cpp | 148 +++++++++++++++++ 20 files changed, 1036 insertions(+), 5 deletions(-) create mode 100644 doc/scalars.md create mode 100644 samples/scalar/BigIntScalar.cpp create mode 100644 samples/scalar/BigIntScalar.h create mode 100644 samples/scalar/CMakeLists.txt create mode 100644 samples/scalar/schema.scalar.graphql create mode 100644 samples/scalar/schema/CMakeLists.txt create mode 100644 samples/scalar/schema/QueryObject.cpp create mode 100644 samples/scalar/schema/QueryObject.h create mode 100644 samples/scalar/schema/ScalarSchema.cpp create mode 100644 samples/scalar/schema/ScalarSchema.h create mode 100644 samples/scalar/schema/scalar_schema_files create mode 100644 test/ScalarTests.cpp diff --git a/README.md b/README.md index a3a0b6e8..3142a9be 100644 --- a/README.md +++ b/README.md @@ -232,6 +232,7 @@ There are some more targeted documents in the [doc](./doc) directory: * [Field Resolvers](./doc/resolvers.md) * [Field Parameters](./doc/fieldparams.md) * [Directives](./doc/directives.md) +* [Custom Scalars](./doc/scalars.md) * [Subscriptions](./doc/subscriptions.md) ### Samples diff --git a/doc/directives.md b/doc/directives.md index faa67a9b..28f258e6 100644 --- a/doc/directives.md +++ b/doc/directives.md @@ -18,4 +18,11 @@ The `schema` can also define custom `directives` which are valid on different elements of the `query`. The library does not handle them automatically, but it will pass them to the `getField` implementations through the optional `graphql::service::FieldParams` struct (see [fieldparams.md](fieldparams.md) -for more information). \ No newline at end of file +for more information). + +There is also one code-generation directive which `schemagen` consumes at build +time and does not serve through introspection: + +* `@cppType(name: String! header: String)`: Map a custom `scalar` type onto a +custom C++ type instead of the default `response::Value`. See +[Custom Scalars](./scalars.md) for details. \ No newline at end of file diff --git a/doc/scalars.md b/doc/scalars.md new file mode 100644 index 00000000..5d59d4c4 --- /dev/null +++ b/doc/scalars.md @@ -0,0 +1,122 @@ +# Custom Scalars + +GraphQL lets a schema declare [custom scalar](https://spec.graphql.org/October2021/#sec-Scalars.Custom-Scalars) +types, e.g.: + +```graphql +scalar DateTime +scalar BigInt +``` + +The wire representation of a scalar is always a `graphql::response::Value` (the JSON-like +discriminated union described in [Query Responses](./responses.md)). By default `schemagen` +generates the resolvers and argument accessors for every custom scalar in terms of +`response::Value`, so you receive and return the value as generic JSON-like data: + +```cpp +service::AwaitableScalar getWhen(service::FieldParams&& params) const override; +``` + +That is convenient, but it forces your implementation to store and manipulate the value as a +`response::Value` even when a dedicated C++ type would be much more natural or efficient (for +example a `std::chrono::system_clock::time_point` for `DateTime`, or a 64-bit integer for a +`BigInt` that does not fit in the 32-bit `response::IntType`). + +## The `@cppType` directive + +You can map a custom scalar onto any C++ type using the `@cppType` directive on the `scalar` +declaration: + +```graphql +scalar BigInt @cppType( + name: "bigint::BigInt" + header: "BigIntScalar.h" +) +``` + +* `name` (required) is the fully-qualified C++ type that `schemagen` uses everywhere the scalar + appears in the generated code, instead of `response::Value`. It may be qualified with any + namespace (`bigint::BigInt`, `my::project::BigInt`, ...). +* `header` (optional) is added as an `#include` at the top of the generated schema header so the + custom type and its conversion specializations are visible to the generated code. + +With the directive above, the generated resolver interface changes to use your type directly: + +```cpp +service::AwaitableScalar getEcho( + service::FieldParams&& params, bigint::BigInt&& valueArg) const override; +``` + +The scalar is still declared to clients exactly as `scalar BigInt` in introspection; `@cppType` +is a code-generation hint only and never appears in the served schema. + +## Providing the conversions + +Because `schemagen` no longer knows how to translate the scalar to and from the `response::Value` +wire representation, you provide that translation by specializing three members of the +`graphql::service` templates. These are the type-erased boundary between your C++ type and the +JSON-like data on the wire: + +```cpp +namespace graphql::service { + +// Deserialize an argument or input value into your custom type. +template <> +bigint::BigInt Argument::convert(const response::Value& value); + +// Serialize a resolver result of your custom type back into a response::Value. +template <> +AwaitableResolver Result::convert( + AwaitableScalar result, ResolverParams&& params); + +// Validate a cached response::Value (returned directly by a resolver) for this scalar. +template <> +void Result::validateScalar(const response::Value& value); + +} // namespace graphql::service +``` + +`Result::convert` is usually implemented with the `ModifiedResult::resolve` helper, passing a +callback that turns a `T&&` into a `response::Value`: + +```cpp +template <> +AwaitableResolver Result::convert( + AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), + std::move(params), + [](bigint::BigInt&& value, const ResolverParams&) { + return response::Value { std::to_string(value.value) }; + }); +} +``` + +Declare these specializations in the header named by `@cppType`'s `header` argument so they are +visible to the generated code, and define them in a matching `.cpp` which is compiled and linked +into the schema library. + +## Nullable scalar arguments + +Nullable arguments of built-in scalar types are passed as `std::optional`. So that your custom +scalar behaves the same way (instead of being treated like a generated `INPUT_OBJECT` type, which +would be wrapped in `std::unique_ptr`), specialize the `CustomScalarArgument` trait and inherit +from `std::true_type`: + +```cpp +namespace graphql::service { + +template <> +struct CustomScalarArgument : std::true_type +{ +}; + +} // namespace graphql::service +``` + +## Complete example + +See [`samples/scalar`](../samples/scalar) for a complete, buildable example of a `BigInt` custom +scalar whose C++ storage is a `std::int64_t` (serialized on the wire as a JSON `String` so it keeps +full precision), along with the [`test/ScalarTests.cpp`](../test/ScalarTests.cpp) unit tests which +exercise serializing, deserializing, nullable arguments, and error handling through live queries. diff --git a/include/SchemaLoader.h b/include/SchemaLoader.h index 9aa73444..e246c9ef 100644 --- a/include/SchemaLoader.h +++ b/include/SchemaLoader.h @@ -43,11 +43,24 @@ using TypeNameMap = std::unordered_map; // Scalar types are opaque to the generator, it's up to the service implementation // to handle parsing, validating, and serializing them. We just need to track which // scalar type names have been declared so we recognize the references. +// +// By default a scalar is represented in the generated C++ code with response::Value, but +// the schema author can override that with the @cppType directive to store, serialize, and +// deserialize the scalar as any custom C++ type (e.g. a BigInt): +// +// scalar BigInt @cppType(name: "bigint::BigInt" header: "BigIntScalar.h") +// +// The `name` argument is the fully-qualified C++ type used everywhere the scalar appears in +// the generated resolvers and argument accessors. The optional `header` argument is added as +// an #include in the generated schema header so that the custom type (and its +// service::Argument/service::Result specializations) are visible to the generated code. struct [[nodiscard("unnecessary construction")]] ScalarType { std::string_view type; std::string_view description; std::string_view specifiedByURL {}; + std::string_view cppType {}; + std::string_view cppHeader {}; }; using ScalarTypeList = std::vector; diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index 0e7f2ea6..8fe51ba1 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -629,6 +629,17 @@ struct Argument [[nodiscard("unnecessary conversion")]] static Type convert(const response::Value& value); }; +// Custom scalar C++ types (e.g. those declared with the @cppType schema directive) are usually +// represented with a class or struct rather than one of the built-in types. Specialize this trait +// and inherit from std::true_type so that the custom type is treated as a scalar argument instead +// of a generated INPUT_OBJECT type. That controls whether a nullable argument is wrapped in a +// std::optional (scalar) or a std::unique_ptr (input object), matching the type which schemagen +// declares for the resolver accessor. +template +struct CustomScalarArgument : std::false_type +{ +}; + #ifdef GRAPHQL_DLLEXPORTS // Export all of the built-in converters template <> @@ -652,7 +663,8 @@ namespace { // These types are used as scalar arguments even though they are represented with a class. template concept ScalarArgumentClass = std::is_same_v - || std::is_same_v || std::is_same_v; + || std::is_same_v || std::is_same_v + || CustomScalarArgument::value; // Any non-scalar class used in an argument is a generated INPUT_OBJECT type. template diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index bddfd792..15cee711 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -5,6 +5,7 @@ cmake_minimum_required(VERSION 3.15) add_subdirectory(client) add_subdirectory(learn) +add_subdirectory(scalar) add_subdirectory(today) add_subdirectory(validation) diff --git a/samples/scalar/BigIntScalar.cpp b/samples/scalar/BigIntScalar.cpp new file mode 100644 index 00000000..026c74f9 --- /dev/null +++ b/samples/scalar/BigIntScalar.cpp @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "BigIntScalar.h" + +#include +#include +#include + +using namespace std::literals; + +namespace { + +using namespace graphql; + +// Parse a std::int64_t out of the JSON-like response::Value wire representation. BigInt values are +// serialized as Strings so they survive without the precision loss of a 32-bit response::IntType, +// but we also accept a plain Int for convenience when the value is small enough. +[[nodiscard]] std::int64_t parseBigInt(const response::Value& value) +{ + switch (value.type()) + { + case response::Type::Int: + return static_cast(value.get()); + + case response::Type::String: + { + const auto& str = value.get(); + std::int64_t result = 0; + const auto* first = str.data(); + const auto* last = first + str.size(); + const auto [ptr, ec] = std::from_chars(first, last, result); + + if (ec != std::errc {} || ptr != last) + { + throw service::schema_exception { { "not a valid BigInt value"s } }; + } + + return result; + } + + default: + throw service::schema_exception { { "not a valid BigInt value"s } }; + } +} + +} // namespace + +namespace graphql::service { + +template <> +bigint::BigInt Argument::convert(const response::Value& value) +{ + return bigint::BigInt { parseBigInt(value) }; +} + +template <> +AwaitableResolver Result::convert( + AwaitableScalar result, ResolverParams&& params) +{ + return ModifiedResult::resolve(std::move(result), + std::move(params), + [](bigint::BigInt&& value, const ResolverParams&) { + return response::Value { std::to_string(value.value) }; + }); +} + +template <> +void Result::validateScalar(const response::Value& value) +{ + // Reuse the argument parser to confirm the cached wire representation is well formed. + static_cast(parseBigInt(value)); +} + +} // namespace graphql::service diff --git a/samples/scalar/BigIntScalar.h b/samples/scalar/BigIntScalar.h new file mode 100644 index 00000000..419070af --- /dev/null +++ b/samples/scalar/BigIntScalar.h @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#ifndef BIGINTSCALAR_H +#define BIGINTSCALAR_H + +#include "graphqlservice/GraphQLService.h" + +#include + +// This is the custom C++ type backing the GraphQL `BigInt` scalar. It is associated with the +// scalar in schema.scalar.graphql using the `@cppType` directive: +// +// scalar BigInt @cppType(name: "bigint::BigInt" header: "BigIntScalar.h") +// +// A BigInt can hold values which do not fit in the 32-bit response::IntType, so instead of forcing +// the field accessors to work with response::Value, schemagen generates the resolvers and argument +// accessors in terms of bigint::BigInt. The service::Argument and service::Result specializations +// below are the type-erased bridge that (de)serializes the value to and from the JSON-like +// response::Value wire representation (here, a String so the full 64-bit precision survives). +namespace bigint { + +struct [[nodiscard("unnecessary construction")]] BigInt +{ + BigInt() noexcept = default; + + explicit BigInt(std::int64_t value) noexcept + : value { value } + { + } + + [[nodiscard]] bool operator==(const BigInt& rhs) const noexcept + { + return value == rhs.value; + } + + std::int64_t value = 0; +}; + +} // namespace bigint + +namespace graphql::service { + +// Parse a BigInt argument from the request (a JSON String, or an Int for small values). +template <> +[[nodiscard("unnecessary conversion")]] bigint::BigInt Argument::convert( + const response::Value& value); + +// Treat bigint::BigInt as a scalar argument (wrapped in std::optional when nullable) rather than a +// generated INPUT_OBJECT type (which would be wrapped in std::unique_ptr). +template <> +struct CustomScalarArgument : std::true_type +{ +}; + +// Serialize a BigInt result back into a response::Value (a JSON String). +template <> +[[nodiscard("unnecessary conversion")]] AwaitableResolver Result::convert( + AwaitableScalar result, ResolverParams&& params); + +// Validate that a cached response::Value for this scalar is the expected wire representation. +template <> +void Result::validateScalar(const response::Value& value); + +} // namespace graphql::service + +#endif // BIGINTSCALAR_H diff --git a/samples/scalar/CMakeLists.txt b/samples/scalar/CMakeLists.txt new file mode 100644 index 00000000..8f9ca45d --- /dev/null +++ b/samples/scalar/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +cmake_minimum_required(VERSION 3.15) + +# scalargraphql demonstrates a custom scalar (BigInt) whose C++ storage is a dedicated type +# (bigint::BigInt) instead of response::Value. See schema.scalar.graphql and BigIntScalar.h. The +# custom scalar (de)serialization in BigIntScalar.cpp is compiled into the scalar_schema library +# (see schema/CMakeLists.txt), so this is just a friendly alias target for the sample. +add_subdirectory(schema) + +add_library(scalargraphql INTERFACE) +target_link_libraries(scalargraphql INTERFACE scalar_schema) +target_include_directories(scalargraphql INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/samples/scalar/schema.scalar.graphql b/samples/scalar/schema.scalar.graphql new file mode 100644 index 00000000..06c7fe6b --- /dev/null +++ b/samples/scalar/schema.scalar.graphql @@ -0,0 +1,24 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +# This sample demonstrates a custom scalar whose C++ storage is NOT response::Value. +# +# The @cppType directive tells schemagen to use the bigint::BigInt C++ type (declared in +# BigIntScalar.h) for this scalar everywhere it appears in the generated resolvers and argument +# accessors, instead of the default response::Value. See samples/scalar/BigIntScalar.h for the +# service::Argument/service::Result specializations which serialize and deserialize the value. +# +# BigInt values are too large to fit in the 32-bit response::IntType, so on the wire they are +# represented as a JSON String, while the C++ side stores a std::int64_t. +scalar BigInt @cppType(name: "bigint::BigInt" header: "BigIntScalar.h") + +type Query { + "Echo a BigInt argument straight back out, round-tripping through bigint::BigInt." + echo(value: BigInt!): BigInt! + + "Add two BigInt values together on the C++ side and return the result." + add(left: BigInt! right: BigInt!): BigInt! + + "Return an optional BigInt, or null when no value is provided." + maybe(value: BigInt): BigInt +} diff --git a/samples/scalar/schema/CMakeLists.txt b/samples/scalar/schema/CMakeLists.txt new file mode 100644 index 00000000..1515320c --- /dev/null +++ b/samples/scalar/schema/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +cmake_minimum_required(VERSION 3.15) + +# Normally this would be handled by find_package(cppgraphqlgen CONFIG). +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake) + +if(GRAPHQL_UPDATE_SAMPLES) + update_graphql_schema_files(scalar ../schema.scalar.graphql Scalar scalar --stubs) +endif() + +add_graphql_schema_target(scalar) + +if(TARGET scalar_schema) + # The generated schema header #includes "BigIntScalar.h" (via the @cppType directive) and the + # generated resolvers reference the service::Argument/service::Result specializations defined in + # BigIntScalar.cpp, so compile that translation unit into the schema library itself. This keeps + # the custom scalar's (de)serialization together with the generated code that depends on it and + # avoids a circular dependency between two static libraries. + target_sources(scalar_schema PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../BigIntScalar.cpp) + target_include_directories(scalar_schema PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..) +endif() diff --git a/samples/scalar/schema/QueryObject.cpp b/samples/scalar/schema/QueryObject.cpp new file mode 100644 index 00000000..f718a7e6 --- /dev/null +++ b/samples/scalar/schema/QueryObject.cpp @@ -0,0 +1,134 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#include "QueryObject.h" + +#include "graphqlservice/internal/Introspection.h" + +#include "graphqlservice/introspection/SchemaObject.h" +#include "graphqlservice/introspection/TypeObject.h" + +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace graphql::scalar { +namespace object { + +Query::Query(std::unique_ptr pimpl) noexcept + : service::Object{ getTypeNames(), getResolvers() } + , _schema { GetSchema() } + , _pimpl { std::move(pimpl) } +{ +} + +service::TypeNames Query::getTypeNames() const noexcept +{ + return { + R"gql(Query)gql"sv + }; +} + +service::ResolverMap Query::getResolvers() const noexcept +{ + return { + { R"gql(add)gql"sv, [this](service::ResolverParams&& params) { return resolveAdd(std::move(params)); } }, + { R"gql(echo)gql"sv, [this](service::ResolverParams&& params) { return resolveEcho(std::move(params)); } }, + { R"gql(maybe)gql"sv, [this](service::ResolverParams&& params) { return resolveMaybe(std::move(params)); } }, + { R"gql(__type)gql"sv, [this](service::ResolverParams&& params) { return resolve_type(std::move(params)); } }, + { R"gql(__schema)gql"sv, [this](service::ResolverParams&& params) { return resolve_schema(std::move(params)); } }, + { R"gql(__typename)gql"sv, [this](service::ResolverParams&& params) { return resolve_typename(std::move(params)); } } + }; +} + +void Query::beginSelectionSet(const service::SelectionSetParams& params) const +{ + _pimpl->beginSelectionSet(params); +} + +void Query::endSelectionSet(const service::SelectionSetParams& params) const +{ + _pimpl->endSelectionSet(params); +} + +service::AwaitableResolver Query::resolveEcho(service::ResolverParams&& params) const +{ + auto argValue = service::ModifiedArgument::require("value", params.arguments); + std::unique_lock resolverLock(_resolverMutex); + service::SelectionSetParams selectionSetParams { static_cast(params) }; + auto directives = std::move(params.fieldDirectives); + auto result = _pimpl->getEcho(service::FieldParams { std::move(selectionSetParams), std::move(directives) }, std::move(argValue)); + resolverLock.unlock(); + + return service::ModifiedResult::convert(std::move(result), std::move(params)); +} + +service::AwaitableResolver Query::resolveAdd(service::ResolverParams&& params) const +{ + auto argLeft = service::ModifiedArgument::require("left", params.arguments); + auto argRight = service::ModifiedArgument::require("right", params.arguments); + std::unique_lock resolverLock(_resolverMutex); + service::SelectionSetParams selectionSetParams { static_cast(params) }; + auto directives = std::move(params.fieldDirectives); + auto result = _pimpl->getAdd(service::FieldParams { std::move(selectionSetParams), std::move(directives) }, std::move(argLeft), std::move(argRight)); + resolverLock.unlock(); + + return service::ModifiedResult::convert(std::move(result), std::move(params)); +} + +service::AwaitableResolver Query::resolveMaybe(service::ResolverParams&& params) const +{ + auto argValue = service::ModifiedArgument::require("value", params.arguments); + std::unique_lock resolverLock(_resolverMutex); + service::SelectionSetParams selectionSetParams { static_cast(params) }; + auto directives = std::move(params.fieldDirectives); + auto result = _pimpl->getMaybe(service::FieldParams { std::move(selectionSetParams), std::move(directives) }, std::move(argValue)); + resolverLock.unlock(); + + return service::ModifiedResult::convert(std::move(result), std::move(params)); +} + +service::AwaitableResolver Query::resolve_typename(service::ResolverParams&& params) const +{ + return service::Result::convert(std::string{ R"gql(Query)gql" }, std::move(params)); +} + +service::AwaitableResolver Query::resolve_schema(service::ResolverParams&& params) const +{ + return service::Result::convert(std::static_pointer_cast(std::make_shared(std::make_shared(_schema))), std::move(params)); +} + +service::AwaitableResolver Query::resolve_type(service::ResolverParams&& params) const +{ + auto argName = service::ModifiedArgument::require("name", params.arguments); + const auto& baseType = _schema->LookupType(argName); + std::shared_ptr result { baseType ? std::make_shared(std::make_shared(baseType)) : nullptr }; + + return service::ModifiedResult::convert(result, std::move(params)); +} + +} // namespace object + +void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema) +{ + typeQuery->AddFields({ + schema::Field::Make(R"gql(echo)gql"sv, R"md(Echo a BigInt argument straight back out, round-tripping through bigint::BigInt.)md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(BigInt)gql"sv)), { + schema::InputValue::Make(R"gql(value)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(BigInt)gql"sv)), R"gql()gql"sv) + }), + schema::Field::Make(R"gql(add)gql"sv, R"md(Add two BigInt values together on the C++ side and return the result.)md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(BigInt)gql"sv)), { + schema::InputValue::Make(R"gql(left)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(BigInt)gql"sv)), R"gql()gql"sv), + schema::InputValue::Make(R"gql(right)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(BigInt)gql"sv)), R"gql()gql"sv) + }), + schema::Field::Make(R"gql(maybe)gql"sv, R"md(Return an optional BigInt, or null when no value is provided.)md"sv, std::nullopt, schema->LookupType(R"gql(BigInt)gql"sv), { + schema::InputValue::Make(R"gql(value)gql"sv, R"md()md"sv, schema->LookupType(R"gql(BigInt)gql"sv), R"gql()gql"sv) + }) + }); +} + +} // namespace graphql::scalar diff --git a/samples/scalar/schema/QueryObject.h b/samples/scalar/schema/QueryObject.h new file mode 100644 index 00000000..c0359063 --- /dev/null +++ b/samples/scalar/schema/QueryObject.h @@ -0,0 +1,194 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef QUERYOBJECT_H +#define QUERYOBJECT_H + +#include "ScalarSchema.h" + +namespace graphql::scalar::object { +namespace methods::QueryHas { + +template +concept getEchoWithParams = requires (TImpl impl, service::FieldParams params, bigint::BigInt valueArg) +{ + { service::AwaitableScalar { impl.getEcho(std::move(params), std::move(valueArg)) } }; +}; + +template +concept getEcho = requires (TImpl impl, bigint::BigInt valueArg) +{ + { service::AwaitableScalar { impl.getEcho(std::move(valueArg)) } }; +}; + +template +concept getAddWithParams = requires (TImpl impl, service::FieldParams params, bigint::BigInt leftArg, bigint::BigInt rightArg) +{ + { service::AwaitableScalar { impl.getAdd(std::move(params), std::move(leftArg), std::move(rightArg)) } }; +}; + +template +concept getAdd = requires (TImpl impl, bigint::BigInt leftArg, bigint::BigInt rightArg) +{ + { service::AwaitableScalar { impl.getAdd(std::move(leftArg), std::move(rightArg)) } }; +}; + +template +concept getMaybeWithParams = requires (TImpl impl, service::FieldParams params, std::optional valueArg) +{ + { service::AwaitableScalar> { impl.getMaybe(std::move(params), std::move(valueArg)) } }; +}; + +template +concept getMaybe = requires (TImpl impl, std::optional valueArg) +{ + { service::AwaitableScalar> { impl.getMaybe(std::move(valueArg)) } }; +}; + +template +concept beginSelectionSet = requires (TImpl impl, const service::SelectionSetParams params) +{ + { impl.beginSelectionSet(params) }; +}; + +template +concept endSelectionSet = requires (TImpl impl, const service::SelectionSetParams params) +{ + { impl.endSelectionSet(params) }; +}; + +} // namespace methods::QueryHas + +class [[nodiscard("unnecessary construction")]] Query final + : public service::Object +{ +private: + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveEcho(service::ResolverParams&& params) const; + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveAdd(service::ResolverParams&& params) const; + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolveMaybe(service::ResolverParams&& params) const; + + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolve_typename(service::ResolverParams&& params) const; + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolve_schema(service::ResolverParams&& params) const; + [[nodiscard("unnecessary call")]] service::AwaitableResolver resolve_type(service::ResolverParams&& params) const; + + std::shared_ptr _schema; + + struct [[nodiscard("unnecessary construction")]] Concept + { + virtual ~Concept() = default; + + virtual void beginSelectionSet(const service::SelectionSetParams& params) const = 0; + virtual void endSelectionSet(const service::SelectionSetParams& params) const = 0; + + [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar getEcho(service::FieldParams&& params, bigint::BigInt&& valueArg) const = 0; + [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar getAdd(service::FieldParams&& params, bigint::BigInt&& leftArg, bigint::BigInt&& rightArg) const = 0; + [[nodiscard("unnecessary call")]] virtual service::AwaitableScalar> getMaybe(service::FieldParams&& params, std::optional&& valueArg) const = 0; + }; + + template + struct [[nodiscard("unnecessary construction")]] Model final + : Concept + { + explicit Model(std::shared_ptr pimpl) noexcept + : _pimpl { std::move(pimpl) } + { + } + + [[nodiscard("unnecessary call")]] service::AwaitableScalar getEcho(service::FieldParams&& params, bigint::BigInt&& valueArg) const override + { + if constexpr (methods::QueryHas::getEchoWithParams) + { + return { _pimpl->getEcho(std::move(params), std::move(valueArg)) }; + } + else if constexpr (methods::QueryHas::getEcho) + { + return { _pimpl->getEcho(std::move(valueArg)) }; + } + else + { + throw service::unimplemented_method(R"ex(Query::getEcho)ex"); + } + } + + [[nodiscard("unnecessary call")]] service::AwaitableScalar getAdd(service::FieldParams&& params, bigint::BigInt&& leftArg, bigint::BigInt&& rightArg) const override + { + if constexpr (methods::QueryHas::getAddWithParams) + { + return { _pimpl->getAdd(std::move(params), std::move(leftArg), std::move(rightArg)) }; + } + else if constexpr (methods::QueryHas::getAdd) + { + return { _pimpl->getAdd(std::move(leftArg), std::move(rightArg)) }; + } + else + { + throw service::unimplemented_method(R"ex(Query::getAdd)ex"); + } + } + + [[nodiscard("unnecessary call")]] service::AwaitableScalar> getMaybe(service::FieldParams&& params, std::optional&& valueArg) const override + { + if constexpr (methods::QueryHas::getMaybeWithParams) + { + return { _pimpl->getMaybe(std::move(params), std::move(valueArg)) }; + } + else if constexpr (methods::QueryHas::getMaybe) + { + return { _pimpl->getMaybe(std::move(valueArg)) }; + } + else + { + throw service::unimplemented_method(R"ex(Query::getMaybe)ex"); + } + } + + void beginSelectionSet(const service::SelectionSetParams& params) const override + { + if constexpr (methods::QueryHas::beginSelectionSet) + { + _pimpl->beginSelectionSet(params); + } + } + + void endSelectionSet(const service::SelectionSetParams& params) const override + { + if constexpr (methods::QueryHas::endSelectionSet) + { + _pimpl->endSelectionSet(params); + } + } + + private: + const std::shared_ptr _pimpl; + }; + + explicit Query(std::unique_ptr pimpl) noexcept; + + [[nodiscard("unnecessary call")]] service::TypeNames getTypeNames() const noexcept; + [[nodiscard("unnecessary call")]] service::ResolverMap getResolvers() const noexcept; + + void beginSelectionSet(const service::SelectionSetParams& params) const override; + void endSelectionSet(const service::SelectionSetParams& params) const override; + + const std::unique_ptr _pimpl; + +public: + template + explicit Query(std::shared_ptr pimpl) noexcept + : Query { std::unique_ptr { std::make_unique>(std::move(pimpl)) } } + { + } + + [[nodiscard("unnecessary call")]] static constexpr std::string_view getObjectType() noexcept + { + return { R"gql(Query)gql" }; + } +}; + +} // namespace graphql::scalar::object + +#endif // QUERYOBJECT_H diff --git a/samples/scalar/schema/ScalarSchema.cpp b/samples/scalar/schema/ScalarSchema.cpp new file mode 100644 index 00000000..8d4d6036 --- /dev/null +++ b/samples/scalar/schema/ScalarSchema.cpp @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#include "QueryObject.h" + +#include "graphqlservice/internal/Schema.h" + +#include "graphqlservice/introspection/IntrospectionSchema.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std::literals; + +namespace graphql { +namespace scalar { + +Operations::Operations(std::shared_ptr query) + : service::Request({ + { service::strQuery, query } + }, GetSchema()) + , _query(std::move(query)) +{ +} + +void AddTypesToSchema(const std::shared_ptr& schema) +{ + schema->AddType(R"gql(BigInt)gql"sv, schema::ScalarType::Make(R"gql(BigInt)gql"sv, R"md()md", R"url()url"sv)); + auto typeQuery = schema::ObjectType::Make(R"gql(Query)gql"sv, R"md()md"sv); + schema->AddType(R"gql(Query)gql"sv, typeQuery); + + AddQueryDetails(typeQuery, schema); + + schema->AddQueryType(typeQuery); +} + +std::shared_ptr GetSchema() +{ + static std::weak_ptr s_wpSchema; + auto schema = s_wpSchema.lock(); + + if (!schema) + { + schema = std::make_shared(false, R"md()md"sv); + introspection::AddTypesToSchema(schema); + AddTypesToSchema(schema); + s_wpSchema = schema; + } + + return schema; +} + +} // namespace scalar +} // namespace graphql diff --git a/samples/scalar/schema/ScalarSchema.h b/samples/scalar/schema/ScalarSchema.h new file mode 100644 index 00000000..f2b673b3 --- /dev/null +++ b/samples/scalar/schema/ScalarSchema.h @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +#pragma once + +#ifndef SCALARSCHEMA_H +#define SCALARSCHEMA_H + +#include "graphqlservice/internal/Schema.h" + +// Check if the library version is compatible with schemagen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); + +#include +#include +#include +#include + +#include "BigIntScalar.h" + +namespace graphql { +namespace scalar { +namespace object { + +class Query; + +} // namespace object + +class [[nodiscard("unnecessary construction")]] Operations final + : public service::Request +{ +public: + explicit Operations(std::shared_ptr query); + + template + explicit Operations(std::shared_ptr query) + : Operations { + std::make_shared(std::move(query)) + } + { + } + +private: + std::shared_ptr _query; +}; + +void AddQueryDetails(const std::shared_ptr& typeQuery, const std::shared_ptr& schema); + +std::shared_ptr GetSchema(); + +} // namespace scalar +} // namespace graphql + +#endif // SCALARSCHEMA_H diff --git a/samples/scalar/schema/scalar_schema_files b/samples/scalar/schema/scalar_schema_files new file mode 100644 index 00000000..8707b557 --- /dev/null +++ b/samples/scalar/schema/scalar_schema_files @@ -0,0 +1,2 @@ +ScalarSchema.cpp +QueryObject.cpp diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index b9aeb3c7..224abd00 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -128,6 +128,29 @@ static_assert(graphql::internal::MinorVersion == )cpp" )cpp"; + // Include any headers required by custom scalar C++ types declared with the @cppType + // directive so their type definitions and service::Argument/service::Result specializations + // are visible to the generated code. + if (!_loader.isIntrospection()) + { + bool addedCustomScalarHeader = false; + + for (const auto& scalarType : _loader.getScalarTypes()) + { + if (!scalarType.cppHeader.empty()) + { + headerFile << R"cpp(#include ")cpp" << scalarType.cppHeader << R"cpp(" +)cpp"; + addedCustomScalarHeader = true; + } + } + + if (addedCustomScalarHeader) + { + headerFile << std::endl; + } + } + NamespaceScope graphqlNamespace { headerFile, "graphql" }; NamespaceScope schemaNamespace { headerFile, _loader.getSchemaNamespace() }; NamespaceScope objectNamespace { headerFile, "object", true }; @@ -2861,7 +2884,7 @@ std::string Generator::getArgumentAccessType(const InputField& argument) const n break; case InputFieldType::Scalar: - argumentType << R"cpp(response::Value)cpp"; + argumentType << _loader.getCppType(argument.type); break; } @@ -2887,7 +2910,7 @@ std::string Generator::getResultAccessType(const OutputField& result) const noex break; case OutputFieldType::Scalar: - resultType << R"cpp(response::Value)cpp"; + resultType << _loader.getCppType(result.type); break; } diff --git a/src/SchemaLoader.cpp b/src/SchemaLoader.cpp index 9129ec48..f62d82b4 100644 --- a/src/SchemaLoader.cpp +++ b/src/SchemaLoader.cpp @@ -1019,6 +1019,42 @@ void SchemaLoader::visitScalarTypeExtension(const peg::ast_node& scalarTypeExten scalarType.specifiedByURL = std::move(specifiedByURL); } + else if (directiveName == "cppType"sv) + { + std::string_view cppType; + std::string_view cppHeader; + + peg::on_first_child(directive, + [&cppType, &cppHeader](const peg::ast_node& arguments) { + peg::for_each_child(arguments, + [&cppType, &cppHeader](const peg::ast_node& argument) { + std::string_view argumentName; + + peg::on_first_child(argument, + [&argumentName](const peg::ast_node& name) { + argumentName = name.string_view(); + }); + + if (argumentName == "name"sv) + { + peg::on_first_child(argument, + [&cppType](const peg::ast_node& value) { + cppType = value.unescaped_view(); + }); + } + else if (argumentName == "header"sv) + { + peg::on_first_child(argument, + [&cppHeader](const peg::ast_node& value) { + cppHeader = value.unescaped_view(); + }); + } + }); + }); + + scalarType.cppType = std::move(cppType); + scalarType.cppHeader = std::move(cppHeader); + } }); }); } @@ -1706,7 +1742,11 @@ std::string_view SchemaLoader::getCppType(std::string_view type) const noexcept if (itrScalar != _scalarNames.cend()) { - return s_scalarCppType; + const auto& scalarType = _scalarTypes[itrScalar->second]; + + // Scalars use response::Value by default, but the schema can override that with a + // custom C++ type via the @cppType directive. + return scalarType.cppType.empty() ? s_scalarCppType : scalarType.cppType; } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a3b0d52f..50a5a080 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -60,6 +60,15 @@ target_link_libraries(argument_tests PRIVATE add_bigobj_flag(argument_tests) gtest_add_tests(TARGET argument_tests) +add_executable(scalar_tests ScalarTests.cpp) +target_link_libraries(scalar_tests PRIVATE + scalargraphql + graphqljson + GTest::GTest + GTest::Main) +add_bigobj_flag(scalar_tests) +gtest_add_tests(TARGET scalar_tests) + add_executable(pegtl_combined_tests PegtlCombinedTests.cpp) target_link_libraries(pegtl_combined_tests PRIVATE taocpp::pegtl @@ -122,6 +131,7 @@ if(WIN32 AND BUILD_SHARED_LIBS) add_dependencies(client_tests copy_test_dlls) add_dependencies(nointrospection_tests copy_test_dlls) add_dependencies(argument_tests copy_test_dlls) + add_dependencies(scalar_tests copy_test_dlls) add_dependencies(pegtl_combined_tests copy_test_dlls) add_dependencies(pegtl_executable_tests copy_test_dlls) add_dependencies(pegtl_schema_tests copy_test_dlls) diff --git a/test/ScalarTests.cpp b/test/ScalarTests.cpp new file mode 100644 index 00000000..b677a045 --- /dev/null +++ b/test/ScalarTests.cpp @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include + +#include "BigIntScalar.h" +#include "ScalarSchema.h" + +#include "QueryObject.h" + +#include "graphqlservice/JSONResponse.h" + +#include +#include + +using namespace graphql; + +using namespace std::literals; + +namespace { + +// A minimal implementation of the generated Query interface. The resolvers work directly with the +// custom bigint::BigInt C++ type, never with response::Value, demonstrating that a custom scalar's +// storage is no longer limited to response::Value. +class Query +{ +public: + Query() = default; + + bigint::BigInt getEcho(bigint::BigInt&& valueArg) const + { + return std::move(valueArg); + } + + bigint::BigInt getAdd(bigint::BigInt&& leftArg, bigint::BigInt&& rightArg) const + { + return bigint::BigInt { leftArg.value + rightArg.value }; + } + + std::optional getMaybe(std::optional&& valueArg) const + { + return std::move(valueArg); + } +}; + +[[nodiscard]] std::shared_ptr makeService() +{ + return std::make_shared(std::make_shared()); +} + +[[nodiscard]] response::Value runQuery(std::string_view query, response::Value&& variables) +{ + auto service = makeService(); + auto parsed = peg::parseString(query); + + return service->resolve({ parsed, ""sv, std::move(variables), std::launch::async }).get(); +} + +[[nodiscard]] const response::Value& requireData(const response::Value& result) +{ + auto errorsItr = result.find("errors"); + + EXPECT_TRUE( + errorsItr == result.get().cend() || errorsItr->second.size() == 0) + << response::toJSON(response::Value { result }); + + return result["data"]; +} + +} // namespace + +TEST(BigIntScalarCase, EchoRoundTripsValueLargerThan32Bits) +{ + // 9000000000 does not fit in the 32-bit response::IntType, so it must round-trip through the + // custom bigint::BigInt type and its String wire representation. + constexpr std::int64_t largeValue = 9'000'000'000; + + response::Value variables { response::Type::Map }; + variables.emplace_back("value"s, response::Value { std::to_string(largeValue) }); + + auto result = + runQuery(R"(query($value: BigInt!) { echo(value: $value) })"sv, std::move(variables)); + const auto& data = requireData(result); + + ASSERT_EQ(response::Type::String, data["echo"].type()); + EXPECT_EQ(std::to_string(largeValue), data["echo"].get()); +} + +TEST(BigIntScalarCase, AddComputesWithCustomCppType) +{ + response::Value variables { response::Type::Map }; + variables.emplace_back("left"s, response::Value { "4000000000"s }); + variables.emplace_back("right"s, response::Value { "5000000001"s }); + + auto result = runQuery(R"(query($left: BigInt!, $right: BigInt!) { + add(left: $left right: $right) + })"sv, + std::move(variables)); + const auto& data = requireData(result); + + ASSERT_EQ(response::Type::String, data["add"].type()); + EXPECT_EQ("9000000001"s, data["add"].get()); +} + +TEST(BigIntScalarCase, EchoAcceptsInlineStringLiteral) +{ + auto result = runQuery(R"(query { echo(value: "12345678901234") })"sv, + response::Value { response::Type::Map }); + const auto& data = requireData(result); + + ASSERT_EQ(response::Type::String, data["echo"].type()); + EXPECT_EQ("12345678901234"s, data["echo"].get()); +} + +TEST(BigIntScalarCase, NullableArgumentReturnsNullWhenOmitted) +{ + auto result = runQuery(R"(query { maybe })"sv, response::Value { response::Type::Map }); + const auto& data = requireData(result); + + EXPECT_EQ(response::Type::Null, data["maybe"].type()); +} + +TEST(BigIntScalarCase, NullableArgumentRoundTripsValue) +{ + response::Value variables { response::Type::Map }; + variables.emplace_back("value"s, response::Value { "42"s }); + + auto result = + runQuery(R"(query($value: BigInt) { maybe(value: $value) })"sv, std::move(variables)); + const auto& data = requireData(result); + + ASSERT_EQ(response::Type::String, data["maybe"].type()); + EXPECT_EQ("42"s, data["maybe"].get()); +} + +TEST(BigIntScalarCase, InvalidValueProducesError) +{ + response::Value variables { response::Type::Map }; + variables.emplace_back("value"s, response::Value { "not-a-number"s }); + + auto result = + runQuery(R"(query($value: BigInt!) { echo(value: $value) })"sv, std::move(variables)); + + auto errorsItr = result.find("errors"); + + ASSERT_NE(errorsItr, result.get().cend()); + EXPECT_GT(errorsItr->second.size(), size_t { 0 }); +} From 14af541048a9a3cc1d6628d6e5ef720faf98fb22 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Sep 2026 22:38:36 +0000 Subject: [PATCH 123/123] Add response::AnyScalar: type-erased std::any payload for custom scalars (next) --- README.md | 1 + doc/scalars.md | 68 +++++++++++++++ include/graphqlservice/GraphQLResponse.h | 33 ++++++- src/GraphQLResponse.cpp | 77 ++++++++++++++++- test/AnyScalarTests.cpp | 105 +++++++++++++++++++++++ test/CMakeLists.txt | 10 +++ 6 files changed, 289 insertions(+), 5 deletions(-) create mode 100644 doc/scalars.md create mode 100644 test/AnyScalarTests.cpp diff --git a/README.md b/README.md index a3a0b6e8..52c0e004 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,7 @@ There are some more targeted documents in the [doc](./doc) directory: * [Query Responses](./doc/responses.md) * [JSON Representation](./doc/json.md) * [Field Resolvers](./doc/resolvers.md) +* [Custom Scalar Payloads](./doc/scalars.md) * [Field Parameters](./doc/fieldparams.md) * [Directives](./doc/directives.md) * [Subscriptions](./doc/subscriptions.md) diff --git a/doc/scalars.md b/doc/scalars.md new file mode 100644 index 00000000..d4169f7c --- /dev/null +++ b/doc/scalars.md @@ -0,0 +1,68 @@ +# Custom Scalar Payloads with `AnyScalar` + +A custom `scalar` type in GraphQL IDL (e.g. `scalar DateTime`) is represented by +`schemagen` as a plain `graphql::response::Value`, and its generated resolver +signature never changes. Sometimes, though, the natural C++ representation of a +custom scalar can't be expressed with any of `response::Value`'s built-in +alternatives — for example a `BigInt` backed by `std::int64_t`, which is +too large for the 32-bit `response::IntType`. + +`response::AnyScalar` lets a hand-written resolver embed an arbitrary +`std::any` payload as the value of a scalar field, along with a type-erased +serializer callback that knows how to turn that payload into calls on a +`response::ValueVisitor`: + +```c++ +struct [[nodiscard("unnecessary construction")]] AnyScalar +{ + using Serializer = + std::function&)>; + + std::any value; + Serializer serialize; +}; +``` + +This is purely a runtime extension: it does not touch the schema IDL, +`schemagen`, or any GraphQL directive, and the wire format is still ordinary +JSON produced by whatever the serializer calls on the visitor +(`add_string`, `add_int`, `add_bool`, `start_object`, ...). + +## Opting In + +An implementer constructs a `response::Value` from an `AnyScalar`. The payload +and serializer are stored on the value; when the response is serialized, the +token stream calls the serializer with the visitor for the active JSON backend: + +```c++ +struct Int64Scalar +{ + std::int64_t value = 0; +}; + +response::Value getBigInt() +{ + return response::Value { response::AnyScalar { + std::any { Int64Scalar { 9223372036854775807LL } }, + [](const std::any& payload, + const std::shared_ptr& visitor) { + const auto& scalar = std::any_cast(payload); + // Serialize on the wire as an ordinary JSON string. + visitor->add_string(std::to_string(scalar.value)); + }, + } }; +} +``` + +`response::toJSON(getBigInt())` yields `"9223372036854775807"`. + +## Accessors + +* `bool Value::isAny() const` returns `true` if the value is a `Type::Scalar` + holding an `AnyScalar` payload. +* `SharedAnyScalar Value::releaseAny()` moves the shared payload out of the + value. + +Copying a `Value` that holds an `AnyScalar` shares ownership of the same +payload (no deep copy), and equality compares payloads by shared-pointer +identity. diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index 9a591e33..97bcea87 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -9,8 +9,10 @@ #include "internal/Awaitable.h" #include "internal/DllExports.h" +#include #include #include +#include #include #include #include @@ -39,6 +41,7 @@ enum class [[nodiscard("unnecessary conversion")]] Type : std::uint8_t { }; struct Value; +class ValueVisitor; using MapType = std::vector>; using ListType = std::vector; @@ -162,6 +165,22 @@ template <> GRAPHQLRESPONSE_EXPORT IdType::OpaqueString IdType::release(); #endif // GRAPHQL_DLLEXPORTS +// A type-erased payload for scalar values whose C++ representation can't be expressed with any +// of Value's other alternatives (e.g. a BigInt backed by std::int64_t). The implementer supplies +// both the std::any payload and a serializer that knows how to drive a ValueVisitor with it, so +// this stays a private implementation detail of a hand-written resolver -- it's never exposed to +// the schema definition (no IDL/directive changes) or to the client (the wire format is still +// ordinary JSON, produced by whatever the serializer calls on the visitor). +struct [[nodiscard("unnecessary construction")]] AnyScalar +{ + using Serializer = std::function&)>; + + std::any value; + Serializer serialize; +}; + +using SharedAnyScalar = std::shared_ptr; + template struct ValueTypeTraits { @@ -225,6 +244,7 @@ struct [[nodiscard("unnecessary conversion")]] Value GRAPHQLRESPONSE_EXPORT explicit Value(IntType value); GRAPHQLRESPONSE_EXPORT explicit Value(FloatType value); GRAPHQLRESPONSE_EXPORT explicit Value(IdType&& value); + GRAPHQLRESPONSE_EXPORT explicit Value(AnyScalar&& value); GRAPHQLRESPONSE_EXPORT Value(Value&& other) noexcept; GRAPHQLRESPONSE_EXPORT explicit Value(const Value& other); @@ -241,6 +261,10 @@ struct [[nodiscard("unnecessary conversion")]] Value // Check the Type [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT Type type() const noexcept; + // Check for and release a type-erased AnyScalar payload attached to a Type::Scalar value. + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT bool isAny() const noexcept; + GRAPHQLRESPONSE_EXPORT SharedAnyScalar releaseAny(); + // JSON doesn't distinguish between Type::String, Type::EnumValue, and Type::ID, so if this // value comes from JSON and it's a string we need to track the fact that it can be interpreted // as any of those types. @@ -318,6 +342,7 @@ struct [[nodiscard("unnecessary conversion")]] Value [[nodiscard("unnecessary call")]] bool operator==(const ScalarData& rhs) const; std::unique_ptr scalar; + SharedAnyScalar any; }; using SharedData = std::shared_ptr; @@ -533,6 +558,10 @@ struct [[nodiscard("unnecessary construction")]] ValueToken GRAPHQLRESPONSE_EXPORT explicit ValueToken(OpaqueValue&& value); + using AnyValue = SharedAnyScalar; + + GRAPHQLRESPONSE_EXPORT explicit ValueToken(AnyValue&& value); + struct Reserve { std::size_t capacity; @@ -623,8 +652,8 @@ struct [[nodiscard("unnecessary construction")]] ValueToken private: using variant_type = - std::variant; + std::variant; variant_type _value; }; diff --git a/src/GraphQLResponse.cpp b/src/GraphQLResponse.cpp index cb829ccb..e963ea07 100644 --- a/src/GraphQLResponse.cpp +++ b/src/GraphQLResponse.cpp @@ -524,6 +524,11 @@ bool Value::NullData::operator==(const NullData&) const bool Value::ScalarData::operator==(const ScalarData& rhs) const { + if (any || rhs.any) + { + return any == rhs.any; + } + if (scalar && rhs.scalar) { return *scalar == *rhs.scalar; @@ -626,7 +631,7 @@ void Value::set(ScalarType&& value) throw std::logic_error("Invalid call to Value::set for ScalarType"); } - _data = { ScalarData { std::make_unique(std::move(value)) } }; + _data = { ScalarData { std::make_unique(std::move(value)), {} } }; } template <> @@ -984,6 +989,11 @@ Value::Value(IdType&& value) { } +Value::Value(AnyScalar&& value) + : _data(TypeData { ScalarData { {}, std::make_shared(std::move(value)) } }) +{ +} + Value::Value(Value&& other) noexcept : _data(std::move(other._data)) { @@ -1071,8 +1081,19 @@ Value::Value(const Value& other) break; case Type::Scalar: - _data = { ScalarData { std::make_unique(other.get()) } }; + { + const auto& scalarData = std::get(other._data); + + if (scalarData.any) + { + _data = { ScalarData { {}, scalarData.any } }; + } + else + { + _data = { ScalarData { std::make_unique(other.get()), {} } }; + } break; + } } } @@ -1231,6 +1252,40 @@ Type Value::type() const noexcept return typeOf(_data); } +bool Value::isAny() const noexcept +{ + const auto& typeData = data(); + + if (!std::holds_alternative(typeData)) + { + return false; + } + + return static_cast(std::get(typeData).any); +} + +SharedAnyScalar Value::releaseAny() +{ + if (std::holds_alternative(_data)) + { + *this = Value { *std::get(_data) }; + } + + if (!std::holds_alternative(_data)) + { + throw std::logic_error("Invalid call to Value::releaseAny"); + } + + auto any = std::move(std::get(_data).any); + + if (!any) + { + throw std::logic_error("Invalid call to Value::releaseAny"); + } + + return any; +} + Value&& Value::from_json() noexcept { if (std::holds_alternative(_data)) @@ -1527,6 +1582,11 @@ ValueToken::ValueToken(OpaqueValue&& value) { } +ValueToken::ValueToken(AnyValue&& value) + : _value { std::move(value) } +{ +} + ValueToken::ValueToken(Reserve&& value) : _value { std::move(value) } { @@ -1602,6 +1662,10 @@ void ValueToken::visit(const std::shared_ptr& visitor) && { visitor->add_value(std::move(value)); } + else if constexpr (std::is_same_v) + { + value->serialize(value->value, visitor); + } else if constexpr (std::is_same_v) { visitor->reserve(value.capacity); @@ -1889,7 +1953,14 @@ ValueTokenStream::ValueTokenStream(Value&& value) case Type::Scalar: { - append(ValueTokenStream { value.release() }); + if (value.isAny()) + { + push_back(ValueToken::AnyValue { value.releaseAny() }); + } + else + { + append(ValueTokenStream { value.release() }); + } break; } diff --git a/test/AnyScalarTests.cpp b/test/AnyScalarTests.cpp new file mode 100644 index 00000000..2efdb45f --- /dev/null +++ b/test/AnyScalarTests.cpp @@ -0,0 +1,105 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include + +#include "graphqlservice/GraphQLResponse.h" +#include "graphqlservice/JSONResponse.h" + +#include +#include +#include +#include + +using namespace graphql; + +namespace { + +// A toy custom scalar whose C++ representation (a 64-bit integer) can't be expressed with any of +// response::Value's built-in alternatives, since response::IntType is only 32-bit. A hand-written +// resolver can store this directly and hand it off to the token stream via response::AnyScalar, +// without any schema/codegen changes. +struct Int64Scalar +{ + std::int64_t value = 0; +}; + +// Serialize the payload onto the wire as an ordinary JSON string of the decimal value. +response::AnyScalar makeBigInt(std::int64_t value) +{ + return response::AnyScalar { + std::any { Int64Scalar { value } }, + [](const std::any& payload, const std::shared_ptr& visitor) { + const auto& scalar = std::any_cast(payload); + visitor->add_string(std::to_string(scalar.value)); + }, + }; +} + +} // namespace + +TEST(AnyScalarCase, ConstructAndInspect) +{ + auto value = response::Value { makeBigInt(9223372036854775807LL) }; + + ASSERT_TRUE(response::Type::Scalar == value.type()); + ASSERT_TRUE(value.isAny()); +} + +TEST(AnyScalarCase, SerializeToJSON) +{ + auto value = response::Value { makeBigInt(9223372036854775807LL) }; + const auto json = response::toJSON(std::move(value)); + + ASSERT_EQ(R"js("9223372036854775807")js", json); +} + +TEST(AnyScalarCase, SerializeInsideMap) +{ + response::Value map { response::Type::Map }; + map.emplace_back("bigInt", response::Value { makeBigInt(-9223372036854775807LL) }); + + const auto json = response::toJSON(std::move(map)); + + ASSERT_EQ(R"js({"bigInt":"-9223372036854775807"})js", json); +} + +TEST(AnyScalarCase, CopySharesOwnership) +{ + auto original = response::Value { makeBigInt(42) }; + auto copy = response::Value { original }; + + ASSERT_TRUE(copy.isAny()); + // Copies share ownership of the same AnyScalar payload (no deep copy), so they compare equal. + ASSERT_TRUE(original == copy); +} + +TEST(AnyScalarCase, DistinctPayloadsCompareUnequal) +{ + auto lhs = response::Value { makeBigInt(1) }; + auto rhs = response::Value { makeBigInt(1) }; + + // Even with equal logical values, distinct AnyScalar payloads are compared by identity. + ASSERT_FALSE(lhs == rhs); +} + +TEST(AnyScalarCase, ReleaseAny) +{ + auto value = response::Value { makeBigInt(7) }; + auto payload = value.releaseAny(); + + ASSERT_TRUE(static_cast(payload)); + ASSERT_FALSE(value.isAny()); + + const auto& scalar = std::any_cast(payload->value); + ASSERT_EQ(7, scalar.value); +} + +TEST(AnyScalarCase, PlainScalarIsNotAny) +{ + response::Value scalar { response::Type::Scalar }; + scalar.set(response::Value { 5 }); + + ASSERT_TRUE(response::Type::Scalar == scalar.type()); + ASSERT_FALSE(scalar.isAny()); +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 062f2995..e4dda60d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -100,6 +100,16 @@ target_include_directories(response_tests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include) gtest_add_tests(TARGET response_tests) +add_executable(anyscalar_tests AnyScalarTests.cpp) +target_link_libraries(anyscalar_tests PRIVATE + graphqlservice + graphqljson + GTest::GTest + GTest::Main) +target_include_directories(anyscalar_tests PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../include) +gtest_add_tests(TARGET anyscalar_tests) + if(WIN32 AND BUILD_SHARED_LIBS) add_custom_command(OUTPUT copied_test_dlls COMMAND ${CMAKE_COMMAND} -E copy_if_different