Rework meta creation [skip ci]
This commit is contained in:
parent
067b1e532a
commit
25404eb4a7
12 changed files with 114 additions and 43 deletions
|
@ -2,20 +2,38 @@
|
|||
|
||||
use std::{marker::PhantomData, sync::atomic::AtomicPtr};
|
||||
|
||||
use crate::{meta::MetaType, resolve, Registry};
|
||||
|
||||
/// Default standard behavior of GraphQL types implementation.
|
||||
#[derive(Debug)]
|
||||
pub enum Standard {}
|
||||
|
||||
/// Coercion of behavior types and type parameters.
|
||||
pub struct Coerce<T: ?Sized, From: ?Sized = Standard>(PhantomData<AtomicPtr<Box<From>>>, T);
|
||||
|
||||
impl<T, From: ?Sized> Coerce<T, From> {
|
||||
#[must_use]
|
||||
pub const fn wrap(val: T) -> Self {
|
||||
Self(PhantomData, val)
|
||||
pub const fn wrap(value: T) -> Self {
|
||||
Self(PhantomData, value)
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn coerce<T, From: ?Sized>(val: T) -> Coerce<T, From> {
|
||||
Coerce::wrap(val)
|
||||
pub const fn coerce<T, From: ?Sized>(value: T) -> Coerce<T, From> {
|
||||
Coerce::wrap(value)
|
||||
}
|
||||
|
||||
impl<T, TI, SV, B1, B2> resolve::Type<TI, SV, B1> for Coerce<T, B2>
|
||||
where
|
||||
T: resolve::Type<TI, SV, B2> + ?Sized,
|
||||
TI: ?Sized,
|
||||
B1: ?Sized,
|
||||
B2: ?Sized,
|
||||
{
|
||||
fn meta<'r, 'ti: 'r>(registry: &mut Registry<'r, SV>, type_info: &'ti TI) -> MetaType<'r, SV>
|
||||
where
|
||||
SV: 'r,
|
||||
{
|
||||
T::meta(registry, type_info)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,12 +84,6 @@ where
|
|||
field_path: Arc<FieldPath<'a>>,
|
||||
}
|
||||
|
||||
impl<'r, 'a, Ctx: ?Sized, S> Executor<'r, 'a, Ctx, S> {
|
||||
pub(crate) fn current_type_new(&self) -> &TypeType<'a, S> {
|
||||
&self.current_type
|
||||
}
|
||||
}
|
||||
|
||||
/// Error type for errors that occur during query execution
|
||||
///
|
||||
/// All execution errors contain the source position in the query of the field
|
||||
|
@ -1297,17 +1291,58 @@ impl<'r, S: 'r> Registry<'r, S> {
|
|||
}
|
||||
*/
|
||||
|
||||
/// Builds a [`ScalarMeta`] information for the specified [`?Sized`]
|
||||
/// [`graphql::Type`].
|
||||
/// Builds a [`ScalarMeta`] information for the specified non-[`Sized`]
|
||||
/// [`graphql::Type`], and stores it in this [`Registry`].
|
||||
///
|
||||
/// # Idempotent
|
||||
///
|
||||
/// If this [`Registry`] contains a [`MetaType`] with such [`TypeName`]
|
||||
/// already, then just returns it without doing anything.
|
||||
///
|
||||
/// [`graphql::Type`]: resolve::Type
|
||||
pub fn build_scalar_type_unsized<T, TI>(&mut self, type_info: &TI) -> ScalarMeta<'r, S>
|
||||
/// [`TypeName`]: resolve::TypeName
|
||||
pub fn register_scalar_unsized<'ti, T, TI>(&mut self, type_info: &'ti TI) -> MetaType<'r, S>
|
||||
where
|
||||
T: resolve::TypeName<TI> + resolve::InputValueAsRef<S> + resolve::ScalarToken<S> + ?Sized,
|
||||
TI: ?Sized,
|
||||
'ti: 'r,
|
||||
S: Clone,
|
||||
{
|
||||
// TODO: Allow using references.
|
||||
ScalarMeta::new_unsized::<T, _>(T::type_name(type_info).to_owned())
|
||||
// TODO: Use `drop` instead of `|_| {}` once Rust's inference becomes
|
||||
// better for HRTB closures.
|
||||
self.register_scalar_unsized_with::<T, TI, _>(type_info, |_| {})
|
||||
}
|
||||
|
||||
/// Builds a [`ScalarMeta`] information for the specified non-[`Sized`]
|
||||
/// [`graphql::Type`], allowing to `customize` the created [`ScalarMeta`],
|
||||
/// and stores it in this [`Registry`].
|
||||
///
|
||||
/// # Idempotent
|
||||
///
|
||||
/// If this [`Registry`] contains a [`MetaType`] with such [`TypeName`]
|
||||
/// already, then just returns it without doing anything.
|
||||
///
|
||||
/// [`graphql::Type`]: resolve::Type
|
||||
/// [`TypeName`]: resolve::TypeName
|
||||
pub fn register_scalar_unsized_with<'ti, T, TI, F>(
|
||||
&mut self,
|
||||
type_info: &'ti TI,
|
||||
customize: F,
|
||||
) -> MetaType<'r, S>
|
||||
where
|
||||
T: resolve::TypeName<TI> + resolve::InputValueAsRef<S> + resolve::ScalarToken<S> + ?Sized,
|
||||
TI: ?Sized,
|
||||
'ti: 'r,
|
||||
F: FnOnce(&mut ScalarMeta<'r, S>),
|
||||
S: Clone,
|
||||
{
|
||||
self.entry_type::<T, _>(type_info)
|
||||
.or_insert_with(move || {
|
||||
let mut scalar = ScalarMeta::new_unsized::<T, _>(T::type_name(type_info));
|
||||
customize(&mut scalar);
|
||||
scalar.into_meta()
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
|
||||
/// Creates a [`ListMeta`] type.
|
||||
|
@ -1342,7 +1377,8 @@ impl<'r, S: 'r> Registry<'r, S> {
|
|||
T: resolve::Type<Info, S> + ?Sized,
|
||||
Info: ?Sized,
|
||||
{
|
||||
ListMeta::new(T::meta(self, info).as_type(), expected_size)
|
||||
todo!()
|
||||
//ListMeta::new(T::meta(self, info).as_type(), expected_size)
|
||||
}
|
||||
|
||||
/// Creates a [`NullableMeta`] type.
|
||||
|
@ -1359,13 +1395,13 @@ impl<'r, S: 'r> Registry<'r, S> {
|
|||
/// [`graphql::Type`].
|
||||
///
|
||||
/// [`graphql::Type`]: resolve::Type
|
||||
pub fn build_nullable_type_reworked<T, BH, TI>(&mut self, type_info: &TI) -> NullableMeta<'r>
|
||||
pub fn wrap_nullable<'ti, T, TI>(&mut self, type_info: &'ti TI) -> MetaType<'r, S>
|
||||
where
|
||||
T: resolve::Type<TI, S, BH> + ?Sized,
|
||||
BH: ?Sized,
|
||||
T: resolve::Type<TI, S> + ?Sized,
|
||||
TI: ?Sized,
|
||||
'ti: 'r,
|
||||
{
|
||||
NullableMeta::new(T::meta(self, type_info).as_type())
|
||||
NullableMeta::new(T::meta(self, type_info).into()).into_meta()
|
||||
}
|
||||
|
||||
/// Creates an [`ObjectMeta`] type with the given `fields`.
|
||||
|
|
|
@ -6,9 +6,9 @@ use crate::{
|
|||
};
|
||||
|
||||
pub trait Type<TypeInfo: ?Sized, ScalarValue, Behavior: ?Sized = behavior::Standard> {
|
||||
fn meta<'r>(
|
||||
fn meta<'r, 'ti: 'r>(
|
||||
registry: &mut Registry<'r, ScalarValue>,
|
||||
type_info: &TypeInfo,
|
||||
type_info: &'ti TypeInfo,
|
||||
) -> MetaType<'r, ScalarValue>
|
||||
where
|
||||
ScalarValue: 'r; // TODO: remove?
|
||||
|
|
|
@ -460,6 +460,29 @@ impl<'a, S> MetaType<'a, S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, S> From<MetaType<'a, S>> for Type<'a> {
|
||||
fn from(meta: MetaType<'a, S>) -> Self {
|
||||
match meta {
|
||||
MetaType::Scalar(ScalarMeta { name, .. })
|
||||
| MetaType::Object(ObjectMeta { name, .. })
|
||||
| MetaType::Enum(EnumMeta { name, .. })
|
||||
| MetaType::Interface(InterfaceMeta { name, .. })
|
||||
| MetaType::Union(UnionMeta { name, .. })
|
||||
| MetaType::InputObject(InputObjectMeta { name, .. }) => Type::NonNullNamed(name),
|
||||
MetaType::List(ListMeta {
|
||||
of_type,
|
||||
expected_size,
|
||||
}) => Type::NonNullList(Box::new(of_type), expected_size),
|
||||
MetaType::Nullable(NullableMeta { of_type }) => match of_type {
|
||||
Type::NonNullNamed(inner) => Type::Named(inner),
|
||||
Type::NonNullList(inner, expected_size) => Type::List(inner, expected_size),
|
||||
t => t,
|
||||
},
|
||||
MetaType::Placeholder(PlaceholderMeta { of_type }) => of_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S> ScalarMeta<'a, S> {
|
||||
/// Builds a new [`ScalarMeta`] type with the specified `name`.
|
||||
pub fn new<T>(name: Cow<'a, str>) -> Self
|
||||
|
|
|
@ -15,7 +15,7 @@ where
|
|||
TI: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
fn meta<'r>(registry: &mut Registry<'r, SV>, type_info: &TI) -> MetaType<'r, SV>
|
||||
fn meta<'r, 'ti: 'r>(registry: &mut Registry<'r, SV>, type_info: &'ti TI) -> MetaType<'r, SV>
|
||||
where
|
||||
SV: 'r,
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ where
|
|||
TI: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
fn meta<'r>(registry: &mut Registry<'r, SV>, type_info: &TI) -> MetaType<'r, SV>
|
||||
fn meta<'r, 'ti: 'r>(registry: &mut Registry<'r, SV>, type_info: &'ti TI) -> MetaType<'r, SV>
|
||||
where
|
||||
SV: 'r,
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@ use futures::future;
|
|||
|
||||
use crate::{
|
||||
ast::{FromInputValue, InputValue, ToInputValue},
|
||||
behavior,
|
||||
executor::{ExecutionResult, Executor, Registry},
|
||||
graphql, reflect, resolve,
|
||||
schema::meta::MetaType,
|
||||
|
@ -278,13 +279,11 @@ where
|
|||
TI: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
fn meta<'r>(registry: &mut Registry<'r, SV>, type_info: &TI) -> MetaType<'r, SV>
|
||||
fn meta<'r, 'ti: 'r>(registry: &mut Registry<'r, SV>, type_info: &'ti TI) -> MetaType<'r, SV>
|
||||
where
|
||||
SV: 'r,
|
||||
{
|
||||
registry
|
||||
.build_nullable_type_reworked::<T, BH, _>(type_info)
|
||||
.into_meta()
|
||||
registry.wrap_nullable::<behavior::Coerce<T, BH>, _>(type_info)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use futures::future;
|
||||
|
||||
use crate::{
|
||||
behavior,
|
||||
executor::{ExecutionResult, Executor, Registry},
|
||||
graphql, reflect, resolve,
|
||||
schema::meta::MetaType,
|
||||
|
@ -15,13 +16,11 @@ where
|
|||
TI: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
fn meta<'r>(registry: &mut Registry<'r, SV>, type_info: &TI) -> MetaType<'r, SV>
|
||||
fn meta<'r, 'ti: 'r>(registry: &mut Registry<'r, SV>, type_info: &'ti TI) -> MetaType<'r, SV>
|
||||
where
|
||||
SV: 'r,
|
||||
{
|
||||
registry
|
||||
.build_nullable_type_reworked::<T, BH, _>(type_info)
|
||||
.into_meta()
|
||||
registry.wrap_nullable::<behavior::Coerce<T, BH>, _>(type_info)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ where
|
|||
TI: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
fn meta<'r>(registry: &mut Registry<'r, SV>, type_info: &TI) -> MetaType<'r, SV>
|
||||
fn meta<'r, 'ti: 'r>(registry: &mut Registry<'r, SV>, type_info: &'ti TI) -> MetaType<'r, SV>
|
||||
where
|
||||
SV: 'r,
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ where
|
|||
TI: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
fn meta<'r>(registry: &mut Registry<'r, SV>, type_info: &TI) -> MetaType<'r, SV>
|
||||
fn meta<'r, 'ti: 'r>(registry: &mut Registry<'r, SV>, type_info: &'ti TI) -> MetaType<'r, SV>
|
||||
where
|
||||
SV: 'r,
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ where
|
|||
TI: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
fn meta<'r>(registry: &mut Registry<'r, SV>, type_info: &TI) -> MetaType<'r, SV>
|
||||
fn meta<'r, 'ti: 'r>(registry: &mut Registry<'r, SV>, type_info: &'ti TI) -> MetaType<'r, SV>
|
||||
where
|
||||
SV: 'r,
|
||||
{
|
||||
|
|
|
@ -14,17 +14,11 @@ use crate::{
|
|||
};
|
||||
|
||||
impl<TI: ?Sized, SV: ScalarValue> resolve::Type<TI, SV> for str {
|
||||
fn meta<'r>(registry: &mut Registry<'r, SV>, type_info: &TI) -> MetaType<'r, SV>
|
||||
fn meta<'r, 'ti: 'r>(registry: &mut Registry<'r, SV>, type_info: &'ti TI) -> MetaType<'r, SV>
|
||||
where
|
||||
SV: 'r,
|
||||
{
|
||||
let meta = registry
|
||||
.build_scalar_type_unsized::<Self, _>(type_info)
|
||||
.into_meta();
|
||||
registry
|
||||
.entry_type::<Self, _>(type_info)
|
||||
.or_insert(meta)
|
||||
.clone()
|
||||
registry.register_scalar_unsized::<Self, _>(type_info)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,6 +69,8 @@ where
|
|||
SV: From<String>,
|
||||
{
|
||||
fn to_input_value(&self) -> graphql::InputValue<SV> {
|
||||
// TODO: Remove redundant `.to_owned()` allocation by allowing
|
||||
// `ScalarValue` creation from reference?
|
||||
graphql::InputValue::scalar(self.to_owned())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue