Skip to main content

charon_lib/ids/
mod.rs

1pub mod generator;
2pub mod index_map;
3pub mod index_vec;
4
5pub use generator::Generator;
6pub use index_map::IndexMap;
7pub use index_vec::{Idx, IndexVec};
8
9/// Generate an `Index` index type. We use it because we need manipulate a lot of different indices
10/// (for various kinds of declarations, variables, blocks, etc.).
11/// For sanity, we prevent any confusion between the different kinds of indices by using different
12/// types. The following macro allows us to easily derive those types.
13///
14/// The `name` parameter should contain the name of the module to declare. The `pretty_name`
15/// parameter is used to implement `Id::to_pretty_string`; if not provided, it defaults to `name`.
16#[macro_export]
17macro_rules! generate_index_type {
18    ($name:ident) => {
19        $crate::generate_index_type!($name, stringify!($name));
20    };
21    ($name:ident, $pretty_name:expr) => {
22        index_vec::define_index_type! {
23            #[derive(Default, derive_generic_visitor::Drive, derive_generic_visitor::DriveMut, derive_generic_visitor::DriveTwo)]
24            pub struct $name = u32;
25            MAX_INDEX = u32::MAX as usize;
26        }
27
28        impl $name {
29            pub const ZERO: Self = Self { _raw: 0 };
30            pub const MAX: Self = Self {
31                _raw: Self::MAX_INDEX as u32,
32            };
33            pub fn is_zero(&self) -> bool {
34                self.index() == 0
35            }
36            pub fn to_pretty_string(self) -> String {
37                format!("@{}{}", $pretty_name, self)
38            }
39        }
40
41        impl std::fmt::Display for $name {
42            fn fmt(
43                &self,
44                f: &mut std::fmt::Formatter<'_>,
45            ) -> std::result::Result<(), std::fmt::Error> {
46                f.write_str(self.index().to_string().as_str())
47            }
48        }
49
50        impl<State: ?Sized> serde_state::SerializeState<State> for $name {
51            fn serialize_state<S: serde::ser::Serializer>(
52                &self,
53                _state: &State,
54                serializer: S,
55            ) -> Result<S::Ok, S::Error> {
56                use serde::Serialize;
57                self.index().serialize(serializer)
58            }
59        }
60        impl<'de, State: ?Sized> serde_state::DeserializeState<'de, State> for $name {
61            fn deserialize_state<D: serde::de::Deserializer<'de>>(
62                _state: &State,
63                deserializer: D,
64            ) -> Result<Self, D::Error> {
65                use serde::Deserialize;
66                usize::deserialize(deserializer).map(Self::from_usize)
67            }
68        }
69    };
70}