cynic_parser/values/
ids.rs

1use std::num::NonZeroU32;
2
3use super::{storage::*, ValueStore};
4use crate::{common::IdRange, AstLookup};
5
6macro_rules! make_id {
7    ($name:ident, $output:ident, $field:ident) => {
8        #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
9        pub struct $name(NonZeroU32);
10
11        impl $name {
12            pub(super) fn new(index: usize) -> Self {
13                Self(
14                    NonZeroU32::new(u32::try_from(index + 1).expect("too many indices"))
15                        .expect("also too many indices"),
16                )
17            }
18
19            #[allow(dead_code)]
20            pub(super) fn get(&self) -> usize {
21                (self.0.get() - 1) as usize
22            }
23        }
24
25        impl AstLookup<$name> for ValueStore {
26            type Output = $output;
27
28            fn lookup(&self, index: $name) -> &Self::Output {
29                &self.$field[(index.0.get() - 1) as usize]
30            }
31        }
32    };
33}
34
35make_id!(ValueId, ValueRecord, values);
36make_id!(ConstValueId, ValueRecord, values);
37make_id!(FieldId, FieldRecord, fields);
38make_id!(ConstFieldId, FieldRecord, fields);
39
40// ConstValue can always be treated as a Value but not the
41// other way round
42impl From<ConstValueId> for ValueId {
43    fn from(value: ConstValueId) -> Self {
44        ValueId(value.0)
45    }
46}
47
48macro_rules! impl_id_range_ops {
49    ($name: ident) => {
50        impl crate::common::IdOperations for $name {
51            fn empty_range() -> IdRange<Self> {
52                IdRange::new(Self::new(0), Self::new(0))
53            }
54            fn forward(self) -> Option<Self> {
55                Some(Self(NonZeroU32::new(self.0.get() + 1)?))
56            }
57            fn back(self) -> Option<Self> {
58                Some(Self(NonZeroU32::new(self.0.get() - 1)?))
59            }
60            fn cmp(self, other: Self) -> std::cmp::Ordering {
61                self.0.get().cmp(&other.0.get())
62            }
63            fn distance(lhs: Self, rhs: Self) -> usize {
64                rhs.0.get().saturating_sub(lhs.0.get()) as usize
65            }
66        }
67    };
68}
69
70impl_id_range_ops!(ValueId);
71impl_id_range_ops!(ConstValueId);
72impl_id_range_ops!(FieldId);
73impl_id_range_ops!(ConstFieldId);
74
75make_id!(StringId, str, strings);
76
77impl StringId {
78    pub(crate) fn from_executable_id(id: crate::executable::ids::StringId) -> Self {
79        Self::new(id.get())
80    }
81
82    pub(crate) fn from_type_system_id(id: crate::type_system::ids::StringId) -> Self {
83        Self::new(id.get())
84    }
85}