use apollo_compiler::response::JsonMap;
use serde_json_bytes::Value as JsonValue;
pub(crate) type ObjectValue<'a> = dyn Resolver + 'a;
pub(crate) trait Resolver {
fn type_name(&self) -> &str;
fn resolve_field<'a>(
&'a self,
field_name: &'a str,
arguments: &'a JsonMap,
) -> Result<ResolvedValue<'a>, ResolverError>;
fn skip_field(&self, _field_name: &str) -> bool {
false
}
}
pub(crate) type ResolverError = String;
pub(crate) enum ResolvedValue<'a> {
Leaf(JsonValue),
Object(Box<ObjectValue<'a>>),
List(Box<dyn Iterator<Item = Result<ResolvedValue<'a>, ResolverError>> + 'a>),
}
impl<'a> ResolvedValue<'a> {
#[allow(unused)]
pub(crate) fn null() -> Self {
Self::Leaf(JsonValue::Null)
}
pub(crate) fn leaf(json: impl Into<JsonValue>) -> Self {
Self::Leaf(json.into())
}
pub(crate) fn object(resolver: impl Resolver + 'a) -> Self {
Self::Object(Box::new(resolver))
}
#[allow(unused)]
pub(crate) fn opt_object(opt_resolver: Option<impl Resolver + 'a>) -> Self {
match opt_resolver {
Some(resolver) => Self::Object(Box::new(resolver)),
None => Self::null(),
}
}
pub(crate) fn list<I>(iter: I) -> Self
where
I: IntoIterator<Item = Result<Self, ResolverError>>,
I::IntoIter: 'a,
{
Self::List(Box::new(iter.into_iter()))
}
}