use std::fmt::Display;
use apollo_compiler::Name;
use apollo_compiler::Node;
use apollo_compiler::ast::Value;
use apollo_compiler::executable::Directive;
use apollo_compiler::name;
use serde::Serialize;
use crate::error::FederationError;
use crate::link::argument::directive_optional_string_argument;
use crate::link::argument::directive_optional_variable_boolean_argument;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub(crate) struct DeferDirectiveArguments {
pub(crate) label: Option<String>,
pub(crate) 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"))?
.map(|s| s.to_owned()),
if_: directive_optional_variable_boolean_argument(application, &name!("if"))?,
})
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
pub(crate) struct OperationConditional {
pub(crate) kind: OperationConditionalKind,
pub(crate) value: BooleanOrVariable,
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
Hash,
strum_macros::Display,
strum_macros::EnumIter,
strum_macros::IntoStaticStr,
Serialize,
)]
pub(crate) enum OperationConditionalKind {
#[strum(to_string = "include")]
Include,
#[strum(to_string = "skip")]
Skip,
}
impl OperationConditionalKind {
pub(crate) fn name(&self) -> Name {
match self {
OperationConditionalKind::Include => name!("include"),
OperationConditionalKind::Skip => name!("skip"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
pub(crate) enum BooleanOrVariable {
Boolean(bool),
Variable(Name),
}
impl Display for BooleanOrVariable {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BooleanOrVariable::Boolean(b) => b.fmt(f),
BooleanOrVariable::Variable(name) => name.fmt(f),
}
}
}
impl From<BooleanOrVariable> for Value {
fn from(b: BooleanOrVariable) -> Self {
match b {
BooleanOrVariable::Boolean(b) => Value::Boolean(b),
BooleanOrVariable::Variable(name) => Value::Variable(name),
}
}
}
impl From<BooleanOrVariable> for Node<Value> {
fn from(b: BooleanOrVariable) -> Self {
Node::new(b.into())
}
}