bluejay_visibility/
input_type.rs

1use crate::{
2    Cache, EnumTypeDefinition, InputObjectTypeDefinition, ScalarTypeDefinition, TypeDefinition,
3    Warden,
4};
5use bluejay_core::definition::{
6    self, prelude::*, BaseInputTypeReference, InputTypeReference, SchemaDefinition,
7    TypeDefinitionReference,
8};
9
10pub enum InputType<'a, S: SchemaDefinition + 'a, W: Warden<SchemaDefinition = S> + 'a> {
11    Base(BaseInputTypeReference<'a, Self>, bool),
12    List(Box<Self>, bool),
13}
14
15impl<'a, S: SchemaDefinition + 'a, W: Warden<SchemaDefinition = S> + 'a> InputType<'a, S, W> {
16    pub fn new(inner: &'a S::InputType, cache: &'a Cache<'a, S, W>) -> Option<Self> {
17        match inner.as_ref(cache.inner_schema_definition()) {
18            InputTypeReference::Base(b, required) => {
19                Self::new_base(b, cache).map(|base| Self::Base(base, required))
20            }
21            InputTypeReference::List(inner, required) => {
22                Self::new(inner, cache).map(|inner| Self::List(Box::new(inner), required))
23            }
24        }
25    }
26
27    fn new_base(
28        inner: BaseInputTypeReference<'a, S::InputType>,
29        cache: &'a Cache<'a, S, W>,
30    ) -> Option<BaseInputTypeReference<'a, Self>> {
31        let tdr = match inner {
32            BaseInputTypeReference::BuiltinScalar(bstd) => {
33                TypeDefinitionReference::BuiltinScalar(bstd)
34            }
35            BaseInputTypeReference::CustomScalar(cstd) => {
36                TypeDefinitionReference::CustomScalar(cstd)
37            }
38            BaseInputTypeReference::Enum(etd) => TypeDefinitionReference::Enum(etd),
39            BaseInputTypeReference::InputObject(iotd) => TypeDefinitionReference::InputObject(iotd),
40        };
41
42        cache
43            .get_or_create_type_definition(tdr)
44            .map(|type_definition| match type_definition {
45                TypeDefinition::BuiltinScalar(bstd) => BaseInputTypeReference::BuiltinScalar(*bstd),
46                TypeDefinition::CustomScalar(cstd) => BaseInputTypeReference::CustomScalar(cstd),
47                TypeDefinition::Enum(etd) => BaseInputTypeReference::Enum(etd),
48                TypeDefinition::InputObject(iotd) => BaseInputTypeReference::InputObject(iotd),
49                TypeDefinition::Interface(_)
50                | TypeDefinition::Object(_)
51                | TypeDefinition::Union(_) => {
52                    panic!("Schema definition does not have unique type names");
53                }
54            })
55    }
56
57    pub(crate) fn base(&self) -> BaseInputTypeReference<'a, Self> {
58        match self {
59            Self::Base(base, _) => *base,
60            Self::List(inner, _) => inner.base(),
61        }
62    }
63}
64
65impl<'a, S: SchemaDefinition + 'a, W: Warden<SchemaDefinition = S>> definition::InputType
66    for InputType<'a, S, W>
67{
68    type CustomScalarTypeDefinition = ScalarTypeDefinition<'a, S, W>;
69    type EnumTypeDefinition = EnumTypeDefinition<'a, S, W>;
70    type InputObjectTypeDefinition = InputObjectTypeDefinition<'a, S, W>;
71
72    fn as_ref<
73        'b,
74        S2: SchemaDefinition<
75            CustomScalarTypeDefinition = Self::CustomScalarTypeDefinition,
76            InputObjectTypeDefinition = Self::InputObjectTypeDefinition,
77            EnumTypeDefinition = Self::EnumTypeDefinition,
78        >,
79    >(
80        &'b self,
81        _: &'b S2,
82    ) -> InputTypeReference<'b, Self> {
83        match self {
84            Self::Base(b, required) => InputTypeReference::Base(*b, *required),
85            Self::List(inner, required) => InputTypeReference::List(inner, *required),
86        }
87    }
88
89    fn as_shallow_ref(&self) -> definition::ShallowInputTypeReference<'_, Self> {
90        match self {
91            Self::Base(base, required) => {
92                definition::ShallowInputTypeReference::Base(base.name(), *required)
93            }
94            Self::List(inner, required) => definition::ShallowInputTypeReference::List(
95                std::ops::Deref::deref(inner),
96                *required,
97            ),
98        }
99    }
100}