static typename std::enable_if_t convert()

in include/graphqlservice/GraphQLService.h [927:1024]


	static typename std::enable_if_t<TypeModifier::List == Modifier, AwaitableResolver> convert(
		typename ResultTraits<Type, Modifier, Other...>::future_type result, ResolverParams params)
	{
		if constexpr (!std::is_base_of_v<Object, Type>)
		{
			auto value = result.get_value();

			if (value)
			{
				ModifiedResult::validateScalar<Modifier, Other...>(*value);
				co_return ResolverResult { response::Value {
					std::shared_ptr { std::move(value) } } };
			}
		}

		std::vector<AwaitableResolver> children;
		const auto parentPath = params.errorPath;

		co_await params.launch;

		auto awaitedResult = co_await std::move(result);

		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 } } });

		using vector_type = std::decay_t<decltype(awaitedResult)>;

		if constexpr (!std::is_same_v<std::decay_t<typename vector_type::reference>,
						  typename vector_type::value_type>)
		{
			// Special handling for std::vector<> specializations which don't return a
			// reference to the underlying type, i.e. std::vector<bool> on many platforms.
			// Copy the values from the std::vector<> rather than moving them.
			for (typename vector_type::value_type entry : awaitedResult)
			{
				children.push_back(
					ModifiedResult::convert<Other...>(std::move(entry), ResolverParams(params)));
				++std::get<size_t>(params.errorPath->segment);
			}
		}
		else
		{
			for (auto& entry : awaitedResult)
			{
				children.push_back(
					ModifiedResult::convert<Other...>(std::move(entry), ResolverParams(params)));
				++std::get<size_t>(params.errorPath->segment);
			}
		}

		ResolverResult document { response::Value { response::Type::List } };

		document.data.reserve(children.size());
		std::get<size_t>(params.errorPath->segment) = 0;

		for (auto& child : children)
		{
			try
			{
				co_await params.launch;

				auto value = co_await std::move(child);

				document.data.emplace_back(std::move(value.data));

				if (!value.errors.empty())
				{
					document.errors.splice(document.errors.end(), value.errors);
				}
			}
			catch (schema_exception& scx)
			{
				auto errors = scx.getStructuredErrors();

				if (!errors.empty())
				{
					document.errors.splice(document.errors.end(), errors);
				}
			}
			catch (const std::exception& ex)
			{
				std::ostringstream message;

				message << "Field error name: " << params.fieldName
						<< " unknown error: " << ex.what();

				document.errors.emplace_back(schema_error { message.str(),
					params.getLocation(),
					buildErrorPath(params.errorPath) });
			}

			++std::get<size_t>(params.errorPath->segment);
		}

		co_return document;
	}