1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use crate::prelude::*;

#[derive_group(Serializers)]
#[derive(Clone, Debug, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct IndexVec<I: 'static, T: 'static> {
    pub raw: Vec<T>,
    _marker: std::marker::PhantomData<fn(_: &I)>,
}

#[cfg(feature = "rustc")]
impl<I: rustc_index::Idx, T: Sized> IndexVec<I, T> {
    pub fn into_iter_enumerated(
        self,
    ) -> impl DoubleEndedIterator<Item = (I, T)> + ExactSizeIterator {
        rustc_index::IndexVec::from_raw(self.raw).into_iter_enumerated()
    }
    pub fn into_iter(self) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator {
        self.raw.into_iter()
    }
}

#[cfg(feature = "rustc")]
impl<I: rustc_index::Idx, T: Sized> std::ops::Deref for IndexVec<I, T> {
    type Target = rustc_index::IndexSlice<I, T>;
    fn deref(&self) -> &Self::Target {
        Self::Target::from_raw(&self.raw)
    }
}

#[cfg(feature = "rustc")]
impl<I: rustc_index::Idx, T: Sized> std::ops::DerefMut for IndexVec<I, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        Self::Target::from_raw_mut(&mut self.raw)
    }
}

#[cfg(feature = "rustc")]
impl<I: rustc_index::Idx, T> From<rustc_index::IndexVec<I, T>> for IndexVec<I, T> {
    fn from(val: rustc_index::IndexVec<I, T>) -> Self {
        IndexVec {
            raw: val.raw,
            _marker: std::marker::PhantomData,
        }
    }
}

#[cfg(feature = "rustc")]
impl<S, J: rustc_index::Idx, I: rustc_index::Idx + SInto<S, J>, U: Clone, T: SInto<S, U>>
    SInto<S, IndexVec<J, U>> for rustc_index::IndexSlice<I, T>
{
    fn sinto(&self, s: &S) -> IndexVec<J, U> {
        IndexVec {
            raw: self.raw.sinto(s),
            _marker: std::marker::PhantomData,
        }
    }
}

#[cfg(feature = "rustc")]
impl<I, T> FromIterator<T> for IndexVec<I, T>
where
    I: rustc_index::Idx,
{
    #[inline]
    fn from_iter<It: IntoIterator<Item = T>>(iter: It) -> Self {
        Self {
            raw: Vec::from_iter(iter),
            _marker: std::marker::PhantomData,
        }
    }
}

macro_rules! make_idx_wrapper {
    ($($mod:ident)::+, $type:ident) => {
        #[derive_group(Serializers)]#[derive(Copy, Clone, Eq, Debug, Hash, PartialEq, PartialOrd, Ord, JsonSchema)]
        #[serde(untagged)]
        pub enum $type {
            $type(usize),
        }
        #[cfg(feature = "rustc")]
        const _: () = {
            use rustc_index::Idx;
            type OriginalType = $($mod::)+$type;
            impl Idx for $type {
                fn new(idx: usize) -> Self {
                    $type::$type(idx)
                }
                fn index(self) -> usize {
                    let $type::$type(x) = self;
                    x.index()
                }
            }
            impl<S> SInto<S, $type> for OriginalType {
                fn sinto(&self, _s: &S) -> $type {
                    $type::new(self.index())
                }
            }
        };
    };
}
pub(crate) use make_idx_wrapper;