Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
sachindshinde committed Feb 2, 2024
1 parent fd4fb0e commit a688086
Show file tree
Hide file tree
Showing 8 changed files with 1,515 additions and 69 deletions.
19 changes: 19 additions & 0 deletions src/link/argument.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::error::{FederationError, SingleFederationError};
use crate::link::graphql_definition::BooleanOrVariable;
use apollo_compiler::ast::Value;
use apollo_compiler::schema::{Directive, Name};
use apollo_compiler::{Node, NodeStr};
Expand Down Expand Up @@ -141,3 +142,21 @@ pub(crate) fn directive_required_boolean_argument(
.into()
})
}

pub(crate) fn directive_optional_variable_boolean_argument(
application: &Node<Directive>,
name: &Name,
) -> Result<Option<BooleanOrVariable>, FederationError> {
match application.argument_by_name(name) {
Some(value) => match value.deref() {
Value::Variable(name) => Ok(Some(BooleanOrVariable::Variable(name.clone()))),
Value::Boolean(value) => Ok(Some(BooleanOrVariable::Boolean(*value))),
Value::Null => Ok(None),
_ => Err(FederationError::internal(format!(
"Argument \"{}\" of directive \"@{}\" must be a boolean.",
name, application.name
))),
},
None => Ok(None),
}
}
17 changes: 15 additions & 2 deletions src/link/graphql_definition.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
use apollo_compiler::executable::Name;
use apollo_compiler::NodeStr;
use crate::error::FederationError;
use crate::link::argument::{
directive_optional_string_argument, directive_optional_variable_boolean_argument,
};
use apollo_compiler::executable::{Directive, Name};
use apollo_compiler::{name, Node, NodeStr};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub(crate) struct DeferDirectiveArguments {
label: Option<NodeStr>,
if_: Option<BooleanOrVariable>,
}

pub(crate) fn defer_directive_arguments(
application: &Node<Directive>,
) -> Result<DeferDirectiveArguments, FederationError> {
Ok(DeferDirectiveArguments {
label: directive_optional_string_argument(application, &name!("label"))?,
if_: directive_optional_variable_boolean_argument(application, &name!("if"))?,
})
}

/// This struct is meant for recording the original structure/intent of `@skip`/`@include`
/// applications within the elements of a `GraphPath`. Accordingly, the order of them matters within
/// a `Vec`, and superfluous struct instances aren't elided; `Conditions` is the more appropriate
Expand Down
53 changes: 40 additions & 13 deletions src/query_graph/condition_resolver.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,68 @@
use crate::error::FederationError;
use crate::query_graph::graph_path::{
ExcludedConditions, ExcludedDestinations, OpGraphPathContext,
};
use crate::query_graph::path_tree::OpPathTree;
use crate::query_plan::QueryPlanCost;
use petgraph::graph::EdgeIndex;
use std::sync::Arc;

/// Note that `ConditionResolver`s are guaranteed to be only called for edge with conditions.
pub(crate) trait ConditionResolver {
fn resolve(
&mut self,
edge: EdgeIndex,
context: OpGraphPathContext,
excluded_destinations: ExcludedDestinations,
excluded_conditions: ExcludedConditions,
) -> ConditionResolution;
context: &OpGraphPathContext,
excluded_destinations: &ExcludedDestinations,
excluded_conditions: &ExcludedConditions,
) -> Result<ConditionResolution, FederationError>;
}

// TODO: This could probably be refactored into an enum.
#[derive(Debug, Clone)]
pub(crate) struct ConditionResolution {
satisfied: bool,
cost: QueryPlanCost,
path_tree: Option<OpPathTree>,
// Note that this is not guaranteed to be set even if satistied === false.
unsatisfied_condition_reason: Option<UnsatisfiedConditionReason>,
pub(crate) satisfied: bool,
pub(crate) cost: QueryPlanCost,
pub(crate) path_tree: Option<Arc<OpPathTree>>,
// Note that this is not guaranteed to be set even if satisfied is false.
pub(crate) unsatisfied_condition_reason: Option<UnsatisfiedConditionReason>,
}

#[derive(Debug, Clone)]
pub(crate) enum UnsatisfiedConditionReason {
NoPostRequireKey,
}

impl ConditionResolution {
pub(crate) fn no_conditions() -> Self {
Self {
satisfied: true,
cost: 0,
path_tree: None,
unsatisfied_condition_reason: None,
}
}

pub(crate) fn unsatisfied_conditions() -> Self {
Self {
satisfied: false,
cost: -1,
path_tree: None,
unsatisfied_condition_reason: None,
}
}
}

pub(crate) struct CachingConditionResolver;

impl ConditionResolver for CachingConditionResolver {
fn resolve(
&mut self,
_edge: EdgeIndex,
_context: OpGraphPathContext,
_excluded_destinations: ExcludedDestinations,
_excluded_conditions: ExcludedConditions,
) -> ConditionResolution {
_context: &OpGraphPathContext,
_excluded_destinations: &ExcludedDestinations,
_excluded_conditions: &ExcludedConditions,
) -> Result<ConditionResolution, FederationError> {
todo!()
}
}
Loading

0 comments on commit a688086

Please sign in to comment.