cynic_parser/type_system/
ids.rs1use std::num::NonZeroU32;
2
3use super::{storage::*, DefinitionRecord, TypeSystemDocument};
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 #[allow(dead_code)]
22 pub(super) fn get(&self) -> usize {
23 (self.0.get() - 1) as usize
24 }
25 }
26
27 impl AstLookup<$name> for TypeSystemDocument {
28 type Output = $output;
29
30 fn lookup(&self, index: $name) -> &Self::Output {
31 &self.$field[(index.0.get() - 1) as usize]
32 }
33 }
34 };
35}
36
37macro_rules! impl_id_range_ops {
38 ($name: ident) => {
39 impl crate::common::IdOperations for $name {
40 fn empty_range() -> IdRange<Self> {
41 IdRange::new(Self::new(0), Self::new(0))
42 }
43 fn forward(self) -> Option<Self> {
44 Some(Self(NonZeroU32::new(self.0.get() + 1)?))
45 }
46 fn back(self) -> Option<Self> {
47 Some(Self(NonZeroU32::new(self.0.get() - 1)?))
48 }
49 fn cmp(self, other: Self) -> std::cmp::Ordering {
50 self.0.get().cmp(&other.0.get())
51 }
52 fn distance(lhs: Self, rhs: Self) -> usize {
53 rhs.0.get().saturating_sub(lhs.0.get()) as usize
54 }
55 }
56 };
57}
58
59make_id!(DefinitionId, DefinitionRecord, definitions);
60impl_id_range_ops!(DefinitionId);
61
62make_id!(
63 SchemaDefinitionId,
64 SchemaDefinitionRecord,
65 schema_definitions
66);
67make_id!(
68 RootOperationTypeDefinitionId,
69 RootOperationTypeDefinitionRecord,
70 root_operation_definitions
71);
72impl_id_range_ops!(RootOperationTypeDefinitionId);
73
74make_id!(
75 ScalarDefinitionId,
76 ScalarDefinitionRecord,
77 scalar_definitions
78);
79
80make_id!(
81 ObjectDefinitionId,
82 ObjectDefinitionRecord,
83 object_definitions
84);
85
86make_id!(
87 InterfaceDefinitionId,
88 InterfaceDefinitionRecord,
89 interface_definitions
90);
91
92make_id!(UnionDefinitionId, UnionDefinitionRecord, union_definitions);
93
94make_id!(UnionMemberId, UnionMemberRecord, union_members);
95impl_id_range_ops!(UnionMemberId);
96
97make_id!(EnumDefinitionId, EnumDefinitionRecord, enum_definitions);
98
99make_id!(
100 EnumValueDefinitionId,
101 EnumValueDefinitionRecord,
102 enum_value_definitions
103);
104impl_id_range_ops!(EnumValueDefinitionId);
105
106make_id!(
107 InputObjectDefinitionId,
108 InputObjectDefinitionRecord,
109 input_object_definitions
110);
111
112make_id!(
113 DirectiveDefinitionId,
114 DirectiveDefinitionRecord,
115 directive_definitions
116);
117
118make_id!(FieldDefinitionId, FieldDefinitionRecord, field_definitions);
119impl_id_range_ops!(FieldDefinitionId);
120
121make_id!(
122 InputValueDefinitionId,
123 InputValueDefinitionRecord,
124 input_value_definitions
125);
126impl_id_range_ops!(InputValueDefinitionId);
127
128make_id!(TypeId, TypeRecord, type_references);
129
130make_id!(DirectiveId, DirectiveRecord, directives);
131impl_id_range_ops!(DirectiveId);
132
133make_id!(ArgumentId, ArgumentRecord, arguments);
134impl_id_range_ops!(ArgumentId);
135
136make_id!(DescriptionId, DescriptionRecord, descriptions);
137
138make_id!(BlockStringLiteralId, str, block_strings);
139
140#[derive(Clone, Copy)]
141pub struct StringId(NonZeroU32);
142
143impl StringId {
144 pub(super) fn new(index: usize) -> Self {
145 Self(
146 NonZeroU32::new(u32::try_from(index + 1).expect("too many indices"))
147 .expect("also too many indices"),
148 )
149 }
150
151 pub(crate) fn get(&self) -> usize {
152 (self.0.get() - 1) as usize
153 }
154}
155
156impl AstLookup<StringId> for TypeSystemDocument {
157 type Output = str;
158
159 fn lookup(&self, index: StringId) -> &Self::Output {
160 &self.strings[(index.0.get() - 1) as usize]
161 }
162}
163
164#[derive(Clone, Copy)]
165pub enum StringLiteralId {
166 String(StringId),
167 Block(BlockStringLiteralId),
168}