use std::{borrow::Cow, marker::PhantomData};
use crate::{
QueryVariables,
core::QueryFragment,
schema::{MutationRoot, QueryRoot, SubscriptionRoot},
};
mod builder;
pub use builder::{OperationBuildError, OperationBuilder};
pub struct Operation<QueryFragment, Variables = ()> {
pub query: String,
pub variables: Variables,
pub operation_name: Option<Cow<'static, str>>,
phantom: PhantomData<fn() -> QueryFragment>,
}
impl<F, V> Clone for Operation<F, V>
where
V: Clone,
{
fn clone(&self) -> Self {
Self {
query: self.query.clone(),
variables: self.variables.clone(),
operation_name: self.operation_name.clone(),
phantom: PhantomData,
}
}
}
impl<QueryFragment, Variables> std::fmt::Debug for Operation<QueryFragment, Variables>
where
Variables: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Operation")
.field("query", &self.query)
.field("variables", &self.variables)
.field("operation_name", &self.operation_name)
.finish()
}
}
impl<QueryFragment, Variables> serde::Serialize for Operation<QueryFragment, Variables>
where
Variables: serde::Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeMap;
let mut map_serializer = serializer.serialize_map(Some(2))?;
map_serializer.serialize_entry("query", &self.query)?;
map_serializer.serialize_entry("variables", &self.variables)?;
if let Some(operation_name) = &self.operation_name {
map_serializer.serialize_entry("operationName", &operation_name)?;
}
map_serializer.end()
}
}
impl<Fragment, Variables> Operation<Fragment, Variables>
where
Fragment: QueryFragment,
Variables: QueryVariables,
{
pub fn new(query: String, variables: Variables) -> Self {
Operation {
query,
variables,
operation_name: None,
phantom: PhantomData,
}
}
pub fn query(variables: Variables) -> Self
where
Fragment::SchemaType: QueryRoot,
{
OperationBuilder::query()
.with_variables(variables)
.build()
.expect("to be able to build query")
}
pub fn mutation(variables: Variables) -> Self
where
Fragment::SchemaType: MutationRoot,
{
OperationBuilder::mutation()
.with_variables(variables)
.build()
.expect("to be able to build mutation")
}
}
impl<F, V> AsRef<Operation<F, V>> for Operation<F, V> {
fn as_ref(&self) -> &Operation<F, V> {
self
}
}
pub struct StreamingOperation<ResponseData, Variables = ()> {
inner: Operation<ResponseData, Variables>,
}
impl<Fragment, Variables> StreamingOperation<Fragment, Variables>
where
Fragment: QueryFragment,
Variables: QueryVariables,
{
pub fn subscription(variables: Variables) -> Self
where
Fragment::SchemaType: SubscriptionRoot,
{
let inner = OperationBuilder::subscription()
.with_variables(variables)
.build()
.expect("to be able to build subscription");
StreamingOperation { inner }
}
}
impl<ResponseData, Variables> serde::Serialize for StreamingOperation<ResponseData, Variables>
where
Variables: serde::Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.inner.serialize(serializer)
}
}