cynic_parser/type_system/
ids.rs

1use 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}