fraiseql_core/schema/compiled/
schema_lookup.rs1use super::{
6 directive::DirectiveDefinition, mutation::MutationDefinition, query::QueryDefinition,
7 schema::CompiledSchema,
8};
9use crate::schema::{
10 config_types::NamingConvention,
11 graphql_type_defs::{
12 EnumDefinition, InputObjectDefinition, InterfaceDefinition, TypeDefinition, UnionDefinition,
13 },
14 subscription_types::SubscriptionDefinition,
15};
16
17impl CompiledSchema {
18 pub fn build_indexes(&mut self) {
23 let camel = matches!(self.naming_convention, NamingConvention::CamelCase);
24
25 self.query_index = self
26 .queries
27 .iter()
28 .enumerate()
29 .flat_map(|(i, q)| {
30 let mut entries = vec![(q.name.clone(), i)];
31 if camel {
32 let converted = crate::utils::casing::to_camel_case(&q.name);
33 if converted != q.name {
34 entries.push((converted, i));
35 }
36 }
37 entries
38 })
39 .collect();
40
41 self.mutation_index = self
42 .mutations
43 .iter()
44 .enumerate()
45 .flat_map(|(i, m)| {
46 let mut entries = vec![(m.name.clone(), i)];
47 if camel {
48 let converted = crate::utils::casing::to_camel_case(&m.name);
49 if converted != m.name {
50 entries.push((converted, i));
51 }
52 }
53 entries
54 })
55 .collect();
56
57 self.subscription_index = self
58 .subscriptions
59 .iter()
60 .enumerate()
61 .flat_map(|(i, s)| {
62 let mut entries = vec![(s.name.clone(), i)];
63 if camel {
64 let converted = crate::utils::casing::to_camel_case(&s.name);
65 if converted != s.name {
66 entries.push((converted, i));
67 }
68 }
69 entries
70 })
71 .collect();
72 }
73
74 #[must_use]
80 pub fn display_name(&self, name: &str) -> String {
81 match self.naming_convention {
82 NamingConvention::CamelCase => crate::utils::casing::to_camel_case(name),
83 NamingConvention::Preserve => name.to_string(),
84 }
85 }
86
87 #[must_use]
89 pub fn find_type(&self, name: &str) -> Option<&TypeDefinition> {
90 self.types.iter().find(|t| t.name == name)
91 }
92
93 #[must_use]
99 pub fn type_has_gated_field(&self, type_name: &str) -> bool {
100 self.find_type(type_name).is_some_and(|t| t.fields.iter().any(|f| f.authorize))
101 }
102
103 #[must_use]
109 pub fn has_any_authorize_field(&self) -> bool {
110 self.types.iter().any(|t| t.fields.iter().any(|f| f.authorize))
111 }
112
113 #[must_use]
115 pub fn find_enum(&self, name: &str) -> Option<&EnumDefinition> {
116 self.enums.iter().find(|e| e.name == name)
117 }
118
119 #[must_use]
121 pub fn find_input_type(&self, name: &str) -> Option<&InputObjectDefinition> {
122 self.input_types.iter().find(|i| i.name == name)
123 }
124
125 #[must_use]
127 pub fn find_interface(&self, name: &str) -> Option<&InterfaceDefinition> {
128 self.interfaces.iter().find(|i| i.name == name)
129 }
130
131 #[must_use]
133 pub fn find_implementors(&self, interface_name: &str) -> Vec<&TypeDefinition> {
134 self.types
135 .iter()
136 .filter(|t| t.implements.contains(&interface_name.to_string()))
137 .collect()
138 }
139
140 #[must_use]
142 pub fn find_union(&self, name: &str) -> Option<&UnionDefinition> {
143 self.unions.iter().find(|u| u.name == name)
144 }
145
146 #[must_use]
156 pub fn find_query(&self, name: &str) -> Option<&QueryDefinition> {
157 if self.query_index.is_empty() && !self.queries.is_empty() {
158 self.queries.iter().find(|q| q.name == name).or_else(|| {
159 let snake = crate::utils::casing::to_snake_case(name);
160 self.queries.iter().find(|q| q.name == snake)
161 })
162 } else {
163 self.query_index
164 .get(name)
165 .or_else(|| self.query_index.get(&crate::utils::casing::to_snake_case(name)))
166 .map(|&i| &self.queries[i])
167 }
168 }
169
170 #[must_use]
179 pub fn find_mutation(&self, name: &str) -> Option<&MutationDefinition> {
180 if self.mutation_index.is_empty() && !self.mutations.is_empty() {
181 self.mutations.iter().find(|m| m.name == name).or_else(|| {
182 let snake = crate::utils::casing::to_snake_case(name);
183 self.mutations.iter().find(|m| m.name == snake)
184 })
185 } else {
186 self.mutation_index
187 .get(name)
188 .or_else(|| self.mutation_index.get(&crate::utils::casing::to_snake_case(name)))
189 .map(|&i| &self.mutations[i])
190 }
191 }
192
193 #[must_use]
202 pub fn find_subscription(&self, name: &str) -> Option<&SubscriptionDefinition> {
203 if self.subscription_index.is_empty() && !self.subscriptions.is_empty() {
204 self.subscriptions.iter().find(|s| s.name == name).or_else(|| {
205 let snake = crate::utils::casing::to_snake_case(name);
206 self.subscriptions.iter().find(|s| s.name == snake)
207 })
208 } else {
209 self.subscription_index
210 .get(name)
211 .or_else(|| self.subscription_index.get(&crate::utils::casing::to_snake_case(name)))
212 .map(|&i| &self.subscriptions[i])
213 }
214 }
215
216 #[must_use]
218 pub fn find_directive(&self, name: &str) -> Option<&DirectiveDefinition> {
219 self.directives.iter().find(|d| d.name == name)
220 }
221
222 #[must_use]
224 pub const fn operation_count(&self) -> usize {
225 self.queries.len() + self.mutations.len() + self.subscriptions.len()
226 }
227}