2020-10-15 06:38:10 +00:00
|
|
|
use std::borrow::Cow;
|
2021-11-09 10:52:10 +00:00
|
|
|
use std::pin::Pin;
|
2020-10-15 06:38:10 +00:00
|
|
|
|
|
|
|
use indexmap::IndexMap;
|
|
|
|
|
2021-11-09 10:52:10 +00:00
|
|
|
use crate::futures_util::Stream;
|
2020-09-06 06:16:36 +00:00
|
|
|
use crate::parser::types::Field;
|
2022-03-30 12:54:49 +00:00
|
|
|
use crate::registry::{MetaType, MetaTypeId, Registry};
|
2020-08-09 04:35:15 +00:00
|
|
|
use crate::{
|
2021-11-09 10:52:10 +00:00
|
|
|
CacheControl, ContainerType, Context, ContextSelectionSet, OutputType, Positioned, Response,
|
|
|
|
ServerResult, SimpleObject, SubscriptionType, Value,
|
2020-08-09 04:35:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
pub struct MergedObject<A, B>(pub A, pub B);
|
|
|
|
|
2021-11-09 10:52:10 +00:00
|
|
|
#[async_trait::async_trait]
|
|
|
|
impl<A, B> ContainerType for MergedObject<A, B>
|
|
|
|
where
|
|
|
|
A: ContainerType,
|
|
|
|
B: ContainerType,
|
|
|
|
{
|
|
|
|
async fn resolve_field(&self, ctx: &Context<'_>) -> ServerResult<Option<Value>> {
|
|
|
|
match self.0.resolve_field(ctx).await {
|
|
|
|
Ok(Some(value)) => Ok(Some(value)),
|
|
|
|
Ok(None) => self.1.resolve_field(ctx).await,
|
|
|
|
Err(err) => Err(err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn find_entity(&self, ctx: &Context<'_>, params: &Value) -> ServerResult<Option<Value>> {
|
|
|
|
match self.0.find_entity(ctx, params).await {
|
|
|
|
Ok(Some(value)) => Ok(Some(value)),
|
|
|
|
Ok(None) => self.1.find_entity(ctx, params).await,
|
|
|
|
Err(err) => Err(err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
impl<A, B> OutputType for MergedObject<A, B>
|
|
|
|
where
|
|
|
|
A: OutputType,
|
|
|
|
B: OutputType,
|
|
|
|
{
|
2020-08-09 04:35:15 +00:00
|
|
|
fn type_name() -> Cow<'static, str> {
|
|
|
|
Cow::Owned(format!("{}_{}", A::type_name(), B::type_name()))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_type_info(registry: &mut Registry) -> String {
|
2022-03-30 12:54:49 +00:00
|
|
|
registry.create_output_type::<Self, _>(MetaTypeId::Object, |registry| {
|
2020-08-09 04:35:15 +00:00
|
|
|
let mut fields = IndexMap::new();
|
|
|
|
let mut cc = CacheControl::default();
|
|
|
|
|
2020-10-20 03:49:31 +00:00
|
|
|
if let MetaType::Object {
|
2020-08-09 04:35:15 +00:00
|
|
|
fields: b_fields,
|
|
|
|
cache_control: b_cc,
|
|
|
|
..
|
2021-11-09 10:52:10 +00:00
|
|
|
} = registry.create_fake_output_type::<B>()
|
2020-08-09 04:35:15 +00:00
|
|
|
{
|
2020-10-20 03:49:31 +00:00
|
|
|
fields.extend(b_fields);
|
2020-09-17 08:39:55 +00:00
|
|
|
cc = cc.merge(&b_cc);
|
2020-08-09 04:35:15 +00:00
|
|
|
}
|
|
|
|
|
2021-06-21 01:38:18 +00:00
|
|
|
if let MetaType::Object {
|
|
|
|
fields: a_fields,
|
|
|
|
cache_control: a_cc,
|
|
|
|
..
|
2021-11-09 10:52:10 +00:00
|
|
|
} = registry.create_fake_output_type::<A>()
|
2021-06-21 01:38:18 +00:00
|
|
|
{
|
|
|
|
fields.extend(a_fields);
|
|
|
|
cc = cc.merge(&a_cc);
|
|
|
|
}
|
|
|
|
|
2020-08-09 04:35:15 +00:00
|
|
|
MetaType::Object {
|
|
|
|
name: Self::type_name().to_string(),
|
|
|
|
description: None,
|
|
|
|
fields,
|
|
|
|
cache_control: cc,
|
|
|
|
extends: false,
|
|
|
|
keys: None,
|
2020-12-11 08:03:28 +00:00
|
|
|
visible: None,
|
2021-10-28 08:56:08 +00:00
|
|
|
is_subscription: false,
|
2021-11-08 01:33:20 +00:00
|
|
|
rust_typename: std::any::type_name::<Self>(),
|
2020-08-09 04:35:15 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2021-11-09 10:52:10 +00:00
|
|
|
|
|
|
|
async fn resolve(
|
|
|
|
&self,
|
|
|
|
_ctx: &ContextSelectionSet<'_>,
|
|
|
|
_field: &Positioned<Field>,
|
|
|
|
) -> ServerResult<Value> {
|
|
|
|
unreachable!()
|
|
|
|
}
|
2020-08-09 04:35:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
2021-11-09 10:52:10 +00:00
|
|
|
impl<A, B> SubscriptionType for MergedObject<A, B>
|
2020-08-09 04:35:15 +00:00
|
|
|
where
|
2021-11-09 10:52:10 +00:00
|
|
|
A: SubscriptionType,
|
|
|
|
B: SubscriptionType,
|
2020-08-09 04:35:15 +00:00
|
|
|
{
|
2021-11-09 10:52:10 +00:00
|
|
|
fn type_name() -> Cow<'static, str> {
|
|
|
|
Cow::Owned(format!("{}_{}", A::type_name(), B::type_name()))
|
2020-08-09 04:35:15 +00:00
|
|
|
}
|
2020-10-20 03:49:31 +00:00
|
|
|
|
2021-11-09 10:52:10 +00:00
|
|
|
fn create_type_info(registry: &mut Registry) -> String {
|
|
|
|
registry.create_subscription_type::<Self, _>(|registry| {
|
|
|
|
let mut fields = IndexMap::new();
|
|
|
|
let mut cc = CacheControl::default();
|
|
|
|
|
|
|
|
if let MetaType::Object {
|
|
|
|
fields: b_fields,
|
|
|
|
cache_control: b_cc,
|
|
|
|
..
|
|
|
|
} = registry.create_fake_subscription_type::<B>()
|
|
|
|
{
|
|
|
|
fields.extend(b_fields);
|
|
|
|
cc = cc.merge(&b_cc);
|
|
|
|
}
|
|
|
|
|
|
|
|
if let MetaType::Object {
|
|
|
|
fields: a_fields,
|
|
|
|
cache_control: a_cc,
|
|
|
|
..
|
|
|
|
} = registry.create_fake_subscription_type::<A>()
|
|
|
|
{
|
|
|
|
fields.extend(a_fields);
|
|
|
|
cc = cc.merge(&a_cc);
|
|
|
|
}
|
|
|
|
|
|
|
|
MetaType::Object {
|
|
|
|
name: Self::type_name().to_string(),
|
|
|
|
description: None,
|
|
|
|
fields,
|
|
|
|
cache_control: cc,
|
|
|
|
extends: false,
|
|
|
|
keys: None,
|
|
|
|
visible: None,
|
|
|
|
is_subscription: false,
|
|
|
|
rust_typename: std::any::type_name::<Self>(),
|
|
|
|
}
|
|
|
|
})
|
2020-10-20 03:49:31 +00:00
|
|
|
}
|
2020-08-09 04:35:15 +00:00
|
|
|
|
2021-11-09 10:52:10 +00:00
|
|
|
fn create_field_stream<'a>(
|
|
|
|
&'a self,
|
|
|
|
_ctx: &'a Context<'_>,
|
|
|
|
) -> Option<Pin<Box<dyn Stream<Item = Response> + Send + 'a>>> {
|
2021-06-16 07:08:33 +00:00
|
|
|
unreachable!()
|
2020-08-09 04:35:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
2020-09-18 00:52:13 +00:00
|
|
|
#[derive(SimpleObject, Default)]
|
2021-11-09 10:52:10 +00:00
|
|
|
#[graphql(internal, fake)]
|
2020-08-09 04:35:15 +00:00
|
|
|
pub struct MergedObjectTail;
|
2021-11-09 10:52:10 +00:00
|
|
|
|
|
|
|
impl SubscriptionType for MergedObjectTail {
|
|
|
|
fn type_name() -> Cow<'static, str> {
|
|
|
|
Cow::Borrowed("MergedSubscriptionTail")
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_type_info(registry: &mut Registry) -> String {
|
|
|
|
registry.create_subscription_type::<Self, _>(|_| MetaType::Object {
|
|
|
|
name: "MergedSubscriptionTail".to_string(),
|
|
|
|
description: None,
|
|
|
|
fields: Default::default(),
|
|
|
|
cache_control: Default::default(),
|
|
|
|
extends: false,
|
|
|
|
keys: None,
|
|
|
|
visible: None,
|
|
|
|
is_subscription: false,
|
|
|
|
rust_typename: std::any::type_name::<Self>(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_field_stream<'a>(
|
|
|
|
&'a self,
|
|
|
|
_ctx: &'a Context<'_>,
|
|
|
|
) -> Option<Pin<Box<dyn Stream<Item = Response> + Send + 'a>>> {
|
|
|
|
unreachable!()
|
|
|
|
}
|
|
|
|
}
|