mod definitions;
mod enums;
mod field_types;
mod fields;
mod keys;
mod strings;
mod unions;
mod walkers;
use std::collections::{BTreeMap, BTreeSet};
use itertools::Itertools;
pub(crate) use self::{
definitions::{DefinitionId, DefinitionKind, DefinitionWalker},
field_types::*,
fields::*,
keys::*,
strings::{StringId, StringWalker},
walkers::*,
};
use crate::VecExt;
#[derive(Default)]
pub struct Subgraphs {
pub(super) strings: strings::Strings,
subgraphs: Vec<Subgraph>,
definitions: definitions::Definitions,
enums: enums::Enums,
fields: fields::Fields,
field_types: field_types::FieldTypes,
keys: keys::Keys,
unions: unions::Unions,
definition_names: BTreeMap<(StringId, SubgraphId), DefinitionId>,
field_names: BTreeSet<(StringId, StringId, FieldId)>,
}
impl Subgraphs {
pub fn ingest(&mut self, subgraph_schema: &async_graphql_parser::types::ServiceDocument, name: &str) {
crate::ingest_subgraph::ingest_subgraph(subgraph_schema, name, self);
}
pub(crate) fn iter_definition_groups<'a>(&'a self, mut compose_fn: impl FnMut(&[DefinitionWalker<'a>])) {
let mut buf = Vec::new();
for (_, group) in &self.definition_names.iter().group_by(|((name, _), _)| name) {
buf.clear();
buf.extend(
group
.into_iter()
.map(move |(_, definition_id)| self.walk(*definition_id)),
);
compose_fn(&buf);
}
}
pub(crate) fn iter_field_groups<'a>(&'a self, mut compose_fn: impl FnMut(&[FieldWalker<'a>])) {
let mut buf = Vec::new();
for (_, group) in &self
.field_names
.iter()
.group_by(|(parent_name, field_name, _)| (parent_name, field_name))
{
buf.clear();
buf.extend(group.into_iter().map(|(_, _, field_id)| self.walk(*field_id)));
compose_fn(&buf);
}
}
pub(crate) fn push_subgraph(&mut self, name: &str) -> SubgraphId {
let subgraph = Subgraph {
name: self.strings.intern(name),
};
SubgraphId(self.subgraphs.push_return_idx(subgraph))
}
pub(crate) fn walk<Id>(&self, id: Id) -> Walker<'_, Id> {
Walker { id, subgraphs: self }
}
pub(crate) fn iter_builtin_scalars(&self) -> impl Iterator<Item = StringWalker<'_>> + '_ {
["ID", "String", "Boolean", "Int", "Float"]
.into_iter()
.filter_map(|name| self.strings.lookup(name))
.map(|string| self.walk(string))
}
pub(crate) fn iter_subgraphs(&self) -> impl Iterator<Item = SubgraphWalker<'_>> {
(0..self.subgraphs.len()).map(|idx| self.walk(SubgraphId(idx)))
}
}
pub(crate) struct Subgraph {
name: StringId,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct SubgraphId(usize);
impl SubgraphId {
pub(crate) fn idx(self) -> usize {
self.0
}
}