graphql-composition 0.12.2

An implementation of GraphQL federated schema composition
Documentation
use super::*;
use crate::federated_graph::{DirectiveLocations, display_graphql_string_literal};
use std::fmt::{self, Display};

pub(crate) struct DirectiveDefinition {
    pub(crate) subgraph_id: SubgraphId,
    pub(crate) name: StringId,
    pub(crate) locations: DirectiveLocations,
    pub(crate) arguments: Vec<InputValueDefinition>,
    pub(crate) repeatable: bool,
}

#[derive(Debug, PartialEq, Clone)]
pub(crate) struct InputValueDefinition {
    pub(crate) name: StringId,
    pub(crate) r#type: FieldType,
    pub(crate) default_value: Option<Value>,
    pub(crate) directives: Vec<InputValueDefinitionDirective>,
}

#[derive(Debug, PartialEq, Clone)]
pub(crate) struct InputValueDefinitionDirective {
    pub(crate) name: StringId,
    pub(crate) arguments: Vec<(StringId, Value)>,
}

impl InputValueDefinition {
    pub(crate) fn display<'a>(&'a self, subgraphs: &'a Subgraphs) -> impl fmt::Display + 'a {
        struct DisplayImpl<'a>(&'a InputValueDefinition, &'a Subgraphs);

        impl fmt::Display for DisplayImpl<'_> {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                let DisplayImpl(input_value_definition, subgraphs) = self;

                f.write_str(&subgraphs[input_value_definition.name])?;
                f.write_str(": ")?;
                Display::fmt(&input_value_definition.r#type.display(subgraphs), f)?;

                if let Some(default) = &input_value_definition.default_value {
                    f.write_str(" = ")?;
                    Display::fmt(&default.display(subgraphs), f)?;
                }

                for directive in &input_value_definition.directives {
                    f.write_str(" ")?;
                    Display::fmt(&directive.display(subgraphs), f)?;
                }

                Ok(())
            }
        }

        DisplayImpl(self, subgraphs)
    }
}

impl Value {
    pub(crate) fn display<'a>(&'a self, subgraphs: &'a Subgraphs) -> impl fmt::Display + 'a {
        struct DisplayImpl<'a>(&'a Value, &'a Subgraphs);

        impl fmt::Display for DisplayImpl<'_> {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                let DisplayImpl(value, subgraphs) = self;

                match value {
                    Value::String(string_id) => display_graphql_string_literal(&subgraphs[*string_id], f),
                    Value::Int(int) => Display::fmt(int, f),
                    Value::Float(float) => Display::fmt(float, f),
                    Value::Boolean(b) => Display::fmt(b, f),
                    Value::Enum(string_id) => Display::fmt(&subgraphs[*string_id], f),
                    Value::Object(vec) => {
                        f.write_str("{")?;
                        for (key, value) in vec {
                            Display::fmt(&subgraphs[*key], f)?;
                            f.write_str(": ")?;
                            Display::fmt(&value.display(subgraphs), f)?;
                        }
                        f.write_str("}")
                    }
                    Value::List(vec) => {
                        f.write_str("[")?;
                        for value in vec {
                            Display::fmt(&value.display(subgraphs), f)?;
                        }
                        f.write_str("]")
                    }
                    Value::Null => f.write_str("null"),
                }
            }
        }

        DisplayImpl(self, subgraphs)
    }
}

impl InputValueDefinitionDirective {
    pub(crate) fn display<'a>(&'a self, subgraphs: &'a Subgraphs) -> impl fmt::Display + 'a {
        struct DisplayImpl<'a>(&'a InputValueDefinitionDirective, &'a Subgraphs);

        impl fmt::Display for DisplayImpl<'_> {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                let DisplayImpl(directive, subgraphs) = self;

                f.write_str("@")?;
                f.write_str(&subgraphs[directive.name])?;

                if directive.arguments.is_empty() {
                    return Ok(());
                }

                f.write_str("(")?;

                for argument in &directive.arguments {
                    f.write_str(&subgraphs[argument.0])?;
                    f.write_str(": ")?;
                    argument.1.display(subgraphs).fmt(f)?;
                }

                f.write_str(")")
            }
        }

        DisplayImpl(self, subgraphs)
    }
}