#![allow(missing_docs)]
use std::sync::Arc;
use async_trait::async_trait;
use derivative::Derivative;
use serde::Deserialize;
use serde::Serialize;
use static_assertions::assert_impl_all;
use super::layers::query_analysis::ParsedDocument;
use crate::Context;
use crate::error::QueryPlannerError;
use crate::graphql;
use crate::query_planner::QueryPlan;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, Default)]
#[serde(rename_all = "camelCase")]
pub(crate) struct PlanOptions {
pub(crate) override_conditions: Vec<String>,
}
assert_impl_all!(Request: Send);
#[derive(Derivative)]
#[derivative(Debug)]
pub(crate) struct Request {
pub(crate) query: String,
pub(crate) operation_name: Option<String>,
pub(crate) document: ParsedDocument,
pub(crate) metadata: crate::plugins::authorization::CacheKeyMetadata,
pub(crate) plan_options: PlanOptions,
}
#[buildstructor::buildstructor]
impl Request {
#[builder]
pub(crate) fn new(
query: String,
operation_name: Option<String>,
document: ParsedDocument,
metadata: crate::plugins::authorization::CacheKeyMetadata,
plan_options: PlanOptions,
) -> Request {
Self {
query,
operation_name,
document,
metadata,
plan_options,
}
}
}
#[derive(Clone, Derivative)]
#[derivative(Debug)]
pub(crate) struct CachingRequest {
pub(crate) query: String,
pub(crate) operation_name: Option<String>,
pub(crate) context: Context,
}
#[buildstructor::buildstructor]
impl CachingRequest {
#[builder]
pub(crate) fn new(
query: String,
operation_name: Option<String>,
context: Context,
) -> CachingRequest {
Self {
query,
operation_name,
context,
}
}
}
assert_impl_all!(Response: Send);
pub(crate) struct Response {
pub(crate) content: Option<QueryPlannerContent>,
pub(crate) errors: Vec<graphql::Error>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) enum QueryPlannerContent {
Plan { plan: Arc<QueryPlan> },
Response { response: Box<graphql::Response> },
CachedIntrospectionResponse { response: Box<graphql::Response> },
IntrospectionDisabled,
}
#[buildstructor::buildstructor]
impl Response {
#[builder]
pub(crate) fn new(
content: Option<QueryPlannerContent>,
errors: Vec<graphql::Error>,
) -> Response {
Self { content, errors }
}
}
pub(crate) type BoxService = tower::util::BoxService<Request, Response, QueryPlannerError>;
#[allow(dead_code)]
pub(crate) type BoxCloneService =
tower::util::BoxCloneService<Request, Response, QueryPlannerError>;
#[allow(dead_code)]
pub(crate) type ServiceResult = Result<Response, QueryPlannerError>;
#[allow(dead_code)]
pub(crate) type Body = hyper::Body;
#[allow(dead_code)]
pub(crate) type Error = hyper::Error;
#[async_trait]
pub(crate) trait QueryPlannerPlugin: Send + Sync + 'static {
fn query_planner_service(&self, service: BoxService) -> BoxService;
}