bluejay_visibility/
cache.rs1use crate::{DirectiveDefinition, TypeDefinition, Warden};
2use bluejay_core::definition::{prelude::*, SchemaDefinition, TypeDefinitionReference};
3use elsa::FrozenMap;
4
5pub struct Cache<'a, S: SchemaDefinition, W: Warden<SchemaDefinition = S>> {
6 warden: W,
7 inner_schema_definition: &'a S,
8 type_definitions: FrozenMap<&'a str, Box<TypeDefinition<'a, S, W>>>,
9 directive_definitions: FrozenMap<&'a str, Box<DirectiveDefinition<'a, S, W>>>,
10}
11
12impl<'a, S: SchemaDefinition, W: Warden<SchemaDefinition = S>> Cache<'a, S, W> {
13 pub fn new(warden: W, inner_schema_definition: &'a S) -> Self {
14 Self {
15 warden,
16 inner_schema_definition,
17 type_definitions: FrozenMap::new(),
18 directive_definitions: FrozenMap::new(),
19 }
20 }
21
22 pub fn warden(&self) -> &W {
23 &self.warden
24 }
25
26 pub(crate) fn inner_schema_definition(&self) -> &'a S {
27 self.inner_schema_definition
28 }
29
30 pub(crate) fn get_or_create_type_definition(
31 &'a self,
32 type_definition: TypeDefinitionReference<'a, S::TypeDefinition>,
33 ) -> Option<&'a TypeDefinition<'a, S, W>> {
34 match self.type_definitions.get(type_definition.name()) {
35 Some(existing_type_definition) => self
36 .type_definitions_equal(existing_type_definition.inner(), type_definition)
37 .then_some(existing_type_definition),
38 None => TypeDefinition::new(type_definition, self).map(|td| {
39 self.type_definitions
40 .insert(type_definition.name(), Box::new(td))
41 }),
42 }
43 }
44
45 pub(crate) fn get_type_definition(
46 &'a self,
47 name: &str,
48 ) -> Option<&'a TypeDefinition<'a, S, W>> {
49 self.type_definitions.get(name)
50 }
51
52 pub(crate) fn get_or_create_directive_definition(
53 &'a self,
54 directive_definition: &'a S::DirectiveDefinition,
55 ) -> Option<&'a DirectiveDefinition<'a, S, W>> {
56 self.directive_definitions
57 .get(directive_definition.name())
58 .or_else(|| {
59 DirectiveDefinition::new(directive_definition, self).map(|dd| {
60 self.directive_definitions
61 .insert(directive_definition.name(), Box::new(dd))
62 })
63 })
64 }
65
66 pub(crate) fn get_directive_definition(
67 &'a self,
68 name: &str,
69 ) -> Option<&'a DirectiveDefinition<'a, S, W>> {
70 self.directive_definitions.get(name)
71 }
72
73 fn type_definitions_equal(
74 &self,
75 left: TypeDefinitionReference<'a, S::TypeDefinition>,
76 right: TypeDefinitionReference<'a, S::TypeDefinition>,
77 ) -> bool {
78 match (left, right) {
79 (
80 TypeDefinitionReference::BuiltinScalar(left),
81 TypeDefinitionReference::BuiltinScalar(right),
82 ) => left == right,
83 (
84 TypeDefinitionReference::CustomScalar(left),
85 TypeDefinitionReference::CustomScalar(right),
86 ) => self.warden.scalar_type_definitions_equal(left, right),
87 (TypeDefinitionReference::Enum(left), TypeDefinitionReference::Enum(right)) => {
88 self.warden.enum_type_definitions_equal(left, right)
89 }
90 (
91 TypeDefinitionReference::InputObject(left),
92 TypeDefinitionReference::InputObject(right),
93 ) => self.warden.input_object_type_definitions_equal(left, right),
94 (
95 TypeDefinitionReference::Interface(left),
96 TypeDefinitionReference::Interface(right),
97 ) => self.warden.interface_type_definitions_equal(left, right),
98 (TypeDefinitionReference::Object(left), TypeDefinitionReference::Object(right)) => {
99 self.warden.object_type_definitions_equal(left, right)
100 }
101 (TypeDefinitionReference::Union(left), TypeDefinitionReference::Union(right)) => {
102 self.warden.union_type_definitions_equal(left, right)
103 }
104 _ => false,
105 }
106 }
107}