Skip to main content

apollo_federation/merger/
hints.rs

1use std::sync::LazyLock;
2
3use crate::supergraph::HintCodeDefinition;
4use crate::supergraph::HintLevel;
5
6#[derive(Clone, Debug)]
7pub enum HintCode {
8    InconsistentButCompatibleFieldType,
9    InconsistentButCompatibleArgumentType,
10    InconsistentDefaultValuePresence,
11    InconsistentEntity,
12    InconsistentObjectValueTypeField,
13    InconsistentInterfaceValueTypeField,
14    InconsistentInputObjectField,
15    InconsistentUnionMember,
16    InconsistentEnumValueForInputEnum,
17    InconsistentEnumValueForOutputEnum,
18    InconsistentTypeSystemDirectiveRepeatable,
19    InconsistentTypeSystemDirectiveLocations,
20    InconsistentExecutableDirectivePresence,
21    NoExecutableDirectiveLocationsIntersection,
22    InconsistentExecutableDirectiveRepeatable,
23    InconsistentExecutableDirectiveLocations,
24    InconsistentDescription,
25    InconsistentArgumentPresence,
26    FromSubgraphDoesNotExist,
27    OverriddenFieldCanBeRemoved,
28    OverrideDirectiveCanBeRemoved,
29    OverrideMigrationInProgress,
30    UnusedEnumType,
31    InconsistentNonRepeatableDirectiveArguments,
32    MergedNonRepeatableDirectiveArguments,
33    DirectiveCompositionInfo,
34    DirectiveCompositionWarn,
35    InconsistentRuntimeTypesForShareableReturn,
36    ImplicitlyUpgradedFederationVersion,
37    ContextualArgumentNotContextualInAllSubgraphs,
38    InterfaceKeyMissingImplementationType,
39}
40
41impl HintCode {
42    pub fn definition(&self) -> &'static HintCodeDefinition {
43        match self {
44            HintCode::InconsistentButCompatibleFieldType => &INCONSISTENT_BUT_COMPATIBLE_FIELD_TYPE,
45            HintCode::InconsistentButCompatibleArgumentType => {
46                &INCONSISTENT_BUT_COMPATIBLE_ARGUMENT_TYPE
47            }
48            HintCode::InconsistentDefaultValuePresence => &INCONSISTENT_DEFAULT_VALUE_PRESENCE,
49            HintCode::InconsistentEntity => &INCONSISTENT_ENTITY,
50            HintCode::InconsistentObjectValueTypeField => &INCONSISTENT_OBJECT_VALUE_TYPE_FIELD,
51            HintCode::InconsistentInterfaceValueTypeField => {
52                &INCONSISTENT_INTERFACE_VALUE_TYPE_FIELD
53            }
54            HintCode::InconsistentInputObjectField => &INCONSISTENT_INPUT_OBJECT_FIELD,
55            HintCode::InconsistentUnionMember => &INCONSISTENT_UNION_MEMBER,
56            HintCode::InconsistentEnumValueForInputEnum => &INCONSISTENT_ENUM_VALUE_FOR_INPUT_ENUM,
57            HintCode::InconsistentEnumValueForOutputEnum => {
58                &INCONSISTENT_ENUM_VALUE_FOR_OUTPUT_ENUM
59            }
60            HintCode::InconsistentTypeSystemDirectiveRepeatable => {
61                &INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_REPEATABLE
62            }
63            HintCode::InconsistentTypeSystemDirectiveLocations => {
64                &INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_LOCATIONS
65            }
66            HintCode::InconsistentExecutableDirectivePresence => {
67                &INCONSISTENT_EXECUTABLE_DIRECTIVE_PRESENCE
68            }
69            HintCode::NoExecutableDirectiveLocationsIntersection => {
70                &NO_EXECUTABLE_DIRECTIVE_LOCATIONS_INTERSECTION
71            }
72            HintCode::InconsistentExecutableDirectiveRepeatable => {
73                &INCONSISTENT_EXECUTABLE_DIRECTIVE_REPEATABLE
74            }
75            HintCode::InconsistentExecutableDirectiveLocations => {
76                &INCONSISTENT_EXECUTABLE_DIRECTIVE_LOCATIONS
77            }
78            HintCode::InconsistentDescription => &INCONSISTENT_DESCRIPTION,
79            HintCode::InconsistentArgumentPresence => &INCONSISTENT_ARGUMENT_PRESENCE,
80            HintCode::FromSubgraphDoesNotExist => &FROM_SUBGRAPH_DOES_NOT_EXIST,
81            HintCode::OverriddenFieldCanBeRemoved => &OVERRIDDEN_FIELD_CAN_BE_REMOVED,
82            HintCode::OverrideDirectiveCanBeRemoved => &OVERRIDE_DIRECTIVE_CAN_BE_REMOVED,
83            HintCode::OverrideMigrationInProgress => &OVERRIDE_MIGRATION_IN_PROGRESS,
84            HintCode::UnusedEnumType => &UNUSED_ENUM_TYPE,
85            HintCode::InconsistentNonRepeatableDirectiveArguments => {
86                &INCONSISTENT_NON_REPEATABLE_DIRECTIVE_ARGUMENTS
87            }
88            HintCode::MergedNonRepeatableDirectiveArguments => {
89                &MERGED_NON_REPEATABLE_DIRECTIVE_ARGUMENTS
90            }
91            HintCode::DirectiveCompositionInfo => &DIRECTIVE_COMPOSITION_INFO,
92            HintCode::DirectiveCompositionWarn => &DIRECTIVE_COMPOSITION_WARN,
93            HintCode::InconsistentRuntimeTypesForShareableReturn => {
94                &INCONSISTENT_RUNTIME_TYPES_FOR_SHAREABLE_RETURN
95            }
96            HintCode::ImplicitlyUpgradedFederationVersion => {
97                &IMPLICITLY_UPGRADED_FEDERATION_VERSION
98            }
99            HintCode::ContextualArgumentNotContextualInAllSubgraphs => {
100                &CONTEXTUAL_ARGUMENT_NOT_CONTEXTUAL_IN_ALL_SUBGRAPHS
101            }
102            HintCode::InterfaceKeyMissingImplementationType => {
103                &INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE
104            }
105        }
106    }
107
108    pub fn code(&self) -> &str {
109        self.definition().code()
110    }
111}
112
113pub(crate) static INCONSISTENT_BUT_COMPATIBLE_FIELD_TYPE: LazyLock<HintCodeDefinition> =
114    LazyLock::new(|| {
115        HintCodeDefinition::new(
116            "INCONSISTENT_BUT_COMPATIBLE_FIELD_TYPE",
117            HintLevel::Info,
118            "Field has inconsistent but compatible type across subgraphs",
119        )
120    });
121
122pub(crate) static INCONSISTENT_BUT_COMPATIBLE_ARGUMENT_TYPE: LazyLock<HintCodeDefinition> =
123    LazyLock::new(|| {
124        HintCodeDefinition::new(
125            "INCONSISTENT_BUT_COMPATIBLE_ARGUMENT_TYPE",
126            HintLevel::Info,
127            "Argument has inconsistent but compatible type across subgraphs",
128        )
129    });
130
131pub(crate) static INCONSISTENT_DEFAULT_VALUE_PRESENCE: LazyLock<HintCodeDefinition> =
132    LazyLock::new(|| {
133        HintCodeDefinition::new(
134            "INCONSISTENT_DEFAULT_VALUE_PRESENCE",
135            HintLevel::Warn,
136            "Default value presence is inconsistent across subgraphs",
137        )
138    });
139
140pub(crate) static INCONSISTENT_ENTITY: LazyLock<HintCodeDefinition> = LazyLock::new(|| {
141    HintCodeDefinition::new(
142        "INCONSISTENT_ENTITY",
143        HintLevel::Info,
144        "Entity definition is inconsistent across subgraphs",
145    )
146});
147
148pub(crate) static INCONSISTENT_OBJECT_VALUE_TYPE_FIELD: LazyLock<HintCodeDefinition> =
149    LazyLock::new(|| {
150        HintCodeDefinition::new(
151            "INCONSISTENT_OBJECT_VALUE_TYPE_FIELD",
152            HintLevel::Debug,
153            "Object value type field is inconsistent across subgraphs",
154        )
155    });
156
157pub(crate) static INCONSISTENT_INTERFACE_VALUE_TYPE_FIELD: LazyLock<HintCodeDefinition> =
158    LazyLock::new(|| {
159        HintCodeDefinition::new(
160            "INCONSISTENT_INTERFACE_VALUE_TYPE_FIELD",
161            HintLevel::Debug,
162            "Interface value type field is inconsistent across subgraphs",
163        )
164    });
165
166pub(crate) static INCONSISTENT_INPUT_OBJECT_FIELD: LazyLock<HintCodeDefinition> =
167    LazyLock::new(|| {
168        HintCodeDefinition::new(
169            "INCONSISTENT_INPUT_OBJECT_FIELD",
170            HintLevel::Warn,
171            "Input object field is inconsistent across subgraphs",
172        )
173    });
174
175pub(crate) static INCONSISTENT_UNION_MEMBER: LazyLock<HintCodeDefinition> = LazyLock::new(|| {
176    HintCodeDefinition::new(
177        "INCONSISTENT_UNION_MEMBER",
178        HintLevel::Debug,
179        "Union member is inconsistent across subgraphs",
180    )
181});
182
183pub(crate) static INCONSISTENT_ENUM_VALUE_FOR_INPUT_ENUM: LazyLock<HintCodeDefinition> =
184    LazyLock::new(|| {
185        HintCodeDefinition::new(
186            "INCONSISTENT_ENUM_VALUE_FOR_INPUT_ENUM",
187            HintLevel::Warn,
188            "Enum value for input enum is inconsistent across subgraphs",
189        )
190    });
191
192pub(crate) static INCONSISTENT_ENUM_VALUE_FOR_OUTPUT_ENUM: LazyLock<HintCodeDefinition> =
193    LazyLock::new(|| {
194        HintCodeDefinition::new(
195            "INCONSISTENT_ENUM_VALUE_FOR_OUTPUT_ENUM",
196            HintLevel::Debug,
197            "Enum value for output enum is inconsistent across subgraphs",
198        )
199    });
200
201pub(crate) static INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_REPEATABLE: LazyLock<HintCodeDefinition> =
202    LazyLock::new(|| {
203        HintCodeDefinition::new(
204            "INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_REPEATABLE",
205            HintLevel::Debug,
206            "Type system directive repeatable property is inconsistent across subgraphs",
207        )
208    });
209
210pub(crate) static INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_LOCATIONS: LazyLock<HintCodeDefinition> =
211    LazyLock::new(|| {
212        HintCodeDefinition::new(
213            "INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_LOCATIONS",
214            HintLevel::Debug,
215            "Type system directive locations are inconsistent across subgraphs",
216        )
217    });
218
219pub(crate) static INCONSISTENT_EXECUTABLE_DIRECTIVE_PRESENCE: LazyLock<HintCodeDefinition> =
220    LazyLock::new(|| {
221        HintCodeDefinition::new(
222            "INCONSISTENT_EXECUTABLE_DIRECTIVE_PRESENCE",
223            HintLevel::Warn,
224            "Executable directive presence is inconsistent across subgraphs",
225        )
226    });
227
228pub(crate) static NO_EXECUTABLE_DIRECTIVE_LOCATIONS_INTERSECTION: LazyLock<HintCodeDefinition> =
229    LazyLock::new(|| {
230        HintCodeDefinition::new(
231            "NO_EXECUTABLE_DIRECTIVE_LOCATIONS_INTERSECTION",
232            HintLevel::Warn,
233            "No intersection between executable directive locations across subgraphs",
234        )
235    });
236
237pub(crate) static INCONSISTENT_EXECUTABLE_DIRECTIVE_REPEATABLE: LazyLock<HintCodeDefinition> =
238    LazyLock::new(|| {
239        HintCodeDefinition::new(
240            "INCONSISTENT_EXECUTABLE_DIRECTIVE_REPEATABLE",
241            HintLevel::Warn,
242            "Executable directive repeatable property is inconsistent across subgraphs",
243        )
244    });
245
246pub(crate) static INCONSISTENT_EXECUTABLE_DIRECTIVE_LOCATIONS: LazyLock<HintCodeDefinition> =
247    LazyLock::new(|| {
248        HintCodeDefinition::new(
249            "INCONSISTENT_EXECUTABLE_DIRECTIVE_LOCATIONS",
250            HintLevel::Warn,
251            "Executable directive locations are inconsistent across subgraphs",
252        )
253    });
254
255pub(crate) static INCONSISTENT_DESCRIPTION: LazyLock<HintCodeDefinition> = LazyLock::new(|| {
256    HintCodeDefinition::new(
257        "INCONSISTENT_DESCRIPTION",
258        HintLevel::Warn,
259        "Description is inconsistent across subgraphs",
260    )
261});
262
263pub(crate) static INCONSISTENT_ARGUMENT_PRESENCE: LazyLock<HintCodeDefinition> =
264    LazyLock::new(|| {
265        HintCodeDefinition::new(
266            "INCONSISTENT_ARGUMENT_PRESENCE",
267            HintLevel::Warn,
268            "Argument presence is inconsistent across subgraphs",
269        )
270    });
271
272pub(crate) static FROM_SUBGRAPH_DOES_NOT_EXIST: LazyLock<HintCodeDefinition> =
273    LazyLock::new(|| {
274        HintCodeDefinition::new(
275            "FROM_SUBGRAPH_DOES_NOT_EXIST",
276            HintLevel::Warn,
277            "From subgraph does not exist",
278        )
279    });
280
281pub(crate) static OVERRIDDEN_FIELD_CAN_BE_REMOVED: LazyLock<HintCodeDefinition> =
282    LazyLock::new(|| {
283        HintCodeDefinition::new(
284            "OVERRIDDEN_FIELD_CAN_BE_REMOVED",
285            HintLevel::Info,
286            "Overridden field can be removed",
287        )
288    });
289
290pub(crate) static OVERRIDE_DIRECTIVE_CAN_BE_REMOVED: LazyLock<HintCodeDefinition> =
291    LazyLock::new(|| {
292        HintCodeDefinition::new(
293            "OVERRIDE_DIRECTIVE_CAN_BE_REMOVED",
294            HintLevel::Info,
295            "Override directive can be removed",
296        )
297    });
298
299pub(crate) static OVERRIDE_MIGRATION_IN_PROGRESS: LazyLock<HintCodeDefinition> =
300    LazyLock::new(|| {
301        HintCodeDefinition::new(
302            "OVERRIDE_MIGRATION_IN_PROGRESS",
303            HintLevel::Info,
304            "Override migration is in progress",
305        )
306    });
307
308pub(crate) static UNUSED_ENUM_TYPE: LazyLock<HintCodeDefinition> = LazyLock::new(|| {
309    HintCodeDefinition::new("UNUSED_ENUM_TYPE", HintLevel::Debug, "Enum type is unused")
310});
311
312pub(crate) static INCONSISTENT_NON_REPEATABLE_DIRECTIVE_ARGUMENTS: LazyLock<HintCodeDefinition> =
313    LazyLock::new(|| {
314        HintCodeDefinition::new(
315            "INCONSISTENT_NON_REPEATABLE_DIRECTIVE_ARGUMENTS",
316            HintLevel::Warn,
317            "Non-repeatable directive arguments are inconsistent across subgraphs",
318        )
319    });
320
321pub(crate) static MERGED_NON_REPEATABLE_DIRECTIVE_ARGUMENTS: LazyLock<HintCodeDefinition> =
322    LazyLock::new(|| {
323        HintCodeDefinition::new(
324            "MERGED_NON_REPEATABLE_DIRECTIVE_ARGUMENTS",
325            HintLevel::Info,
326            "Non-repeatable directive arguments have been merged",
327        )
328    });
329
330pub(crate) static DIRECTIVE_COMPOSITION_INFO: LazyLock<HintCodeDefinition> = LazyLock::new(|| {
331    HintCodeDefinition::new(
332        "DIRECTIVE_COMPOSITION_INFO",
333        HintLevel::Info,
334        "Directive composition information",
335    )
336});
337
338pub(crate) static DIRECTIVE_COMPOSITION_WARN: LazyLock<HintCodeDefinition> = LazyLock::new(|| {
339    HintCodeDefinition::new(
340        "DIRECTIVE_COMPOSITION_WARN",
341        HintLevel::Warn,
342        "Directive composition warning",
343    )
344});
345
346pub(crate) static INCONSISTENT_RUNTIME_TYPES_FOR_SHAREABLE_RETURN: LazyLock<HintCodeDefinition> =
347    LazyLock::new(|| {
348        HintCodeDefinition::new(
349            "INCONSISTENT_RUNTIME_TYPES_FOR_SHAREABLE_RETURN",
350            HintLevel::Warn,
351            "Runtime types for shareable return are inconsistent across subgraphs",
352        )
353    });
354
355pub(crate) static IMPLICITLY_UPGRADED_FEDERATION_VERSION: LazyLock<HintCodeDefinition> =
356    LazyLock::new(|| {
357        HintCodeDefinition::new(
358            "IMPLICITLY_UPGRADED_FEDERATION_VERSION",
359            HintLevel::Info,
360            "Federation version has been implicitly upgraded",
361        )
362    });
363
364pub(crate) static CONTEXTUAL_ARGUMENT_NOT_CONTEXTUAL_IN_ALL_SUBGRAPHS: LazyLock<
365    HintCodeDefinition,
366> = LazyLock::new(|| {
367    HintCodeDefinition::new(
368        "CONTEXTUAL_ARGUMENT_NOT_CONTEXTUAL_IN_ALL_SUBGRAPHS",
369        HintLevel::Info,
370        "Contextual argument is not contextual in all subgraphs",
371    )
372});
373
374pub(crate) static INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE: LazyLock<HintCodeDefinition> =
375    LazyLock::new(|| {
376        HintCodeDefinition::new(
377            "INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE",
378            HintLevel::Warn,
379            "Interface key missing implementation type",
380        )
381    });