graphql-composition 0.12.2

An implementation of GraphQL federated schema composition
Documentation
use super::*;

pub(super) fn merge_interface_definitions<'a>(
    ctx: &mut Context<'a>,
    first: &DefinitionView<'a>,
    definitions: &[DefinitionView<'a>],
) {
    let mut directives = collect_composed_directives(definitions.iter().map(|def| def.directives), ctx);
    directives.extend(create_join_type_from_definitions(definitions));
    let interface_description = definitions
        .iter()
        .find_map(|def| def.description)
        .map(|d| ctx.subgraphs[d].as_ref());
    let interface_name = ctx.insert_string(first.name);
    ctx.insert_interface(interface_name, interface_description, directives);

    fields::for_each_field_group(ctx.subgraphs, definitions, |fields| {
        if fields.iter().any(|field| field.directives.shareable(ctx.subgraphs)) {
            ctx.diagnostics.push_fatal(format!(
                "The field {}.{} is marked as shareable but this is not allowed on interfaces.",
                ctx.subgraphs[first.name].as_ref(),
                ctx.subgraphs[fields.first().unwrap().name].as_ref()
            ));
        }
    });

    let fields = object::compose_fields(ctx, definitions, interface_name);
    let field_names = fields.iter().map(|field| field.field_name).collect::<Vec<_>>();
    for field in fields {
        ctx.insert_field(field);
    }

    check_implementers(first.name, &field_names, ctx);
}

fn check_implementers(interface_name: StringId, field_names: &[subgraphs::StringId], ctx: &mut Context<'_>) {
    for implementer_name in ctx.subgraphs.iter_implementers_for_interface(interface_name) {
        for field_name in field_names {
            if !ctx
                .subgraphs
                .iter_definitions_with_name(implementer_name)
                .any(|(_, def)| def.field_by_name(ctx.subgraphs, *field_name).is_some())
            {
                ctx.diagnostics.push_fatal(format!(
                    "The `{}.{}` field is not implemented by `{}`, but it should be.",
                    ctx.subgraphs[interface_name], ctx.subgraphs[*field_name], ctx.subgraphs[implementer_name],
                ));
            }
        }
    }
}