cynic_parser/executable/
ids.rs1use std::num::NonZeroU32;
2
3use super::{storage::*, types::TypeRecord, ExecutableDocument};
4use crate::{common::IdRange, AstLookup};
5
6pub use crate::values::ids::{ConstValueId, ValueId};
7
8macro_rules! make_id {
9 ($name:ident, $output:ident, $field:ident) => {
10 #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
11 pub struct $name(NonZeroU32);
12
13 impl $name {
14 pub(super) fn new(index: usize) -> Self {
15 Self(
16 NonZeroU32::new(u32::try_from(index + 1).expect("too many indices"))
17 .expect("also too many indices"),
18 )
19 }
20 }
21
22 impl AstLookup<$name> for ExecutableDocument {
23 type Output = $output;
24
25 fn lookup(&self, index: $name) -> &Self::Output {
26 &self.$field[(index.0.get() - 1) as usize]
27 }
28 }
29 };
30}
31
32macro_rules! impl_id_range_ops {
33 ($name: ident) => {
34 impl crate::common::IdOperations for $name {
35 fn empty_range() -> IdRange<Self> {
36 IdRange::new(Self::new(0), Self::new(0))
37 }
38 fn forward(self) -> Option<Self> {
39 Some(Self(NonZeroU32::new(self.0.get() + 1)?))
40 }
41 fn back(self) -> Option<Self> {
42 Some(Self(NonZeroU32::new(self.0.get() - 1)?))
43 }
44 fn cmp(self, other: Self) -> std::cmp::Ordering {
45 self.0.get().cmp(&other.0.get())
46 }
47 fn distance(lhs: Self, rhs: Self) -> usize {
48 rhs.0.get().saturating_sub(lhs.0.get()) as usize
49 }
50 }
51 };
52}
53
54make_id!(
55 ExecutableDefinitionId,
56 ExecutableDefinitionRecord,
57 definitions
58);
59impl_id_range_ops!(ExecutableDefinitionId);
60
61make_id!(OperationDefinitionId, OperationDefinitionRecord, operations);
62
63make_id!(FragmentDefinitionId, FragmentDefinitionRecord, fragments);
64
65make_id!(SelectionId, SelectionRecord, selections);
66impl_id_range_ops!(SelectionId);
67
68make_id!(FieldSelectionId, FieldSelectionRecord, field_selections);
69make_id!(InlineFragmentId, InlineFragmentRecord, inline_fragments);
70make_id!(FragmentSpreadId, FragmentSpreadRecord, fragment_spreads);
71
72make_id!(DirectiveId, DirectiveRecord, directives);
73
74make_id!(ArgumentId, ArgumentRecord, arguments);
75
76impl_id_range_ops!(DirectiveId);
77impl_id_range_ops!(ArgumentId);
78
79make_id!(TypeId, TypeRecord, types);
80
81make_id!(VariableDefinitionId, VariableDefinitionRecord, variables);
82impl_id_range_ops!(VariableDefinitionId);
83
84make_id!(BlockStringLiteralId, str, block_strings);
85
86#[derive(Clone, Copy)]
87pub struct StringId(NonZeroU32);
88
89impl StringId {
90 pub(super) fn new(index: usize) -> Self {
91 Self(
92 NonZeroU32::new(u32::try_from(index + 1).expect("too many indices"))
93 .expect("also too many indices"),
94 )
95 }
96
97 pub(crate) fn get(&self) -> usize {
98 (self.0.get() - 1) as usize
99 }
100}
101
102impl AstLookup<StringId> for ExecutableDocument {
103 type Output = str;
104
105 fn lookup(&self, index: StringId) -> &Self::Output {
106 &self.strings[(index.0.get() - 1) as usize]
107 }
108}