From 4ef63e0b7c26b7b39e7e184eaba49ddb36cf0b53 Mon Sep 17 00:00:00 2001
From: tyranron <tyranron@gmail.com>
Date: Tue, 19 Apr 2022 19:04:34 +0300
Subject: [PATCH] Bootstrap, vol.2

---
 juniper/src/executor/mod.rs    |  2 +-
 juniper/src/graphql/resolve.rs | 51 +++++++++++++++++++++++++++++++++-
 juniper/src/resolve/mod.rs     | 19 ++++++++++++-
 3 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs
index 47d5fead..cf35af15 100644
--- a/juniper/src/executor/mod.rs
+++ b/juniper/src/executor/mod.rs
@@ -69,7 +69,7 @@ pub enum FieldPath<'a> {
 /// of the current field stack, context, variables, and errors.
 pub struct Executor<'r, 'a, CtxT, S = DefaultScalarValue>
 where
-    CtxT: 'a,
+    CtxT: ?Sized + 'a,
     S: 'a,
 {
     fragments: &'r HashMap<&'a str, Fragment<'a, S>>,
diff --git a/juniper/src/graphql/resolve.rs b/juniper/src/graphql/resolve.rs
index ef411da2..068115a8 100644
--- a/juniper/src/graphql/resolve.rs
+++ b/juniper/src/graphql/resolve.rs
@@ -1,4 +1,9 @@
-use crate::{executor::Registry, resolve, schema::meta::MetaType, DefaultScalarValue};
+use crate::{
+    executor::{ExecutionResult, Executor, Registry},
+    resolve,
+    schema::meta::MetaType,
+    Arguments, DefaultScalarValue,
+};
 
 pub trait TypeName {
     fn type_name<Info: ?Sized>(info: &Info) -> &str
@@ -31,3 +36,47 @@ impl<T: ?Sized, S> Type<S> for T {
         <Self as resolve::Type<Info, S>>::meta(info, registry)
     }
 }
+
+pub trait Field<S = DefaultScalarValue> {
+    fn resolve_field<Info: ?Sized, Ctx: ?Sized>(
+        &self,
+        info: &Info,
+        field_name: &str,
+        arguments: &Arguments<S>,
+        executor: &Executor<Ctx, S>,
+    ) -> ExecutionResult<S>
+    where
+        Self: resolve::Field<Info, Ctx, S>;
+}
+
+impl<T: ?Sized, S> Field<S> for T {
+    fn resolve_field<Info: ?Sized, Ctx: ?Sized>(
+        &self,
+        info: &Info,
+        field_name: &str,
+        arguments: &Arguments<S>,
+        executor: &Executor<Ctx, S>,
+    ) -> ExecutionResult<S>
+    where
+        Self: resolve::Field<Info, Ctx, S>,
+    {
+        <Self as resolve::Field<Info, Ctx, S>>::resolve_field(
+            self, info, field_name, arguments, executor,
+        )
+    }
+}
+
+pub trait ConcreteTypeName {
+    fn concrete_type_name<'i, Info: ?Sized>(&self, info: &'i Info) -> &'i str
+    where
+        Self: resolve::ConcreteTypeName<Info>;
+}
+
+impl<T: ?Sized> ConcreteTypeName for T {
+    fn concrete_type_name<'i, Info: ?Sized>(&self, info: &'i Info) -> &'i str
+    where
+        Self: resolve::ConcreteTypeName<Info>,
+    {
+        <Self as resolve::ConcreteTypeName<Info>>::concrete_type_name(self, info)
+    }
+}
diff --git a/juniper/src/resolve/mod.rs b/juniper/src/resolve/mod.rs
index 9016b9ac..27b28a19 100644
--- a/juniper/src/resolve/mod.rs
+++ b/juniper/src/resolve/mod.rs
@@ -1,4 +1,8 @@
-use crate::{executor::Registry, schema::meta::MetaType, DefaultScalarValue, ScalarValue};
+use crate::{
+    executor::{ExecutionResult, Executor, Registry},
+    schema::meta::MetaType,
+    Arguments, DefaultScalarValue,
+};
 
 pub trait TypeName<Info: ?Sized> {
     fn type_name(info: &Info) -> &str;
@@ -10,3 +14,16 @@ pub trait Type<Info: ?Sized, S = DefaultScalarValue> {
         S: 'r;
 }
 
+pub trait Field<Info: ?Sized, Ctx: ?Sized, S = DefaultScalarValue> {
+    fn resolve_field(
+        &self,
+        info: &Info,
+        field_name: &str,
+        arguments: &Arguments<S>,
+        executor: &Executor<Ctx, S>,
+    ) -> ExecutionResult<S>;
+}
+
+pub trait ConcreteTypeName<Info: ?Sized> {
+    fn concrete_type_name<'i>(&self, info: &'i Info) -> &'i str;
+}