sway_core/decl_engine/
parsed_id.rs

1use super::{
2    parsed_engine::{ParsedDeclEngine, ParsedDeclEngineGet, ParsedDeclEngineIndex},
3    DeclUniqueId,
4};
5use crate::{
6    engine_threading::{
7        EqWithEngines, HashWithEngines, PartialEqWithEngines, PartialEqWithEnginesContext,
8    },
9    Engines,
10};
11use serde::{Deserialize, Serialize};
12use std::{
13    hash::{DefaultHasher, Hasher},
14    marker::PhantomData,
15    {fmt, hash::Hash},
16};
17use sway_types::{Named, Spanned};
18
19pub type ParsedDeclIdIndexType = usize;
20
21/// An ID used to refer to an item in the [ParsedDeclEngine](super::decl_engine::ParsedDeclEngine)
22pub struct ParsedDeclId<T>(ParsedDeclIdIndexType, PhantomData<T>);
23
24impl<T> fmt::Debug for ParsedDeclId<T> {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        f.debug_tuple("ParsedDeclId").field(&self.0).finish()
27    }
28}
29
30impl<T> ParsedDeclId<T> {
31    pub(crate) fn inner(&self) -> ParsedDeclIdIndexType {
32        self.0
33    }
34
35    pub fn unique_id(&self) -> DeclUniqueId
36    where
37        T: 'static,
38    {
39        let mut hasher = DefaultHasher::default();
40        std::any::TypeId::of::<T>().hash(&mut hasher);
41        self.0.hash(&mut hasher);
42
43        DeclUniqueId(hasher.finish())
44    }
45}
46
47impl<T> Copy for ParsedDeclId<T> {}
48impl<T> Clone for ParsedDeclId<T> {
49    fn clone(&self) -> Self {
50        *self
51    }
52}
53
54impl<T> Eq for ParsedDeclId<T> {}
55impl<T> PartialEq for ParsedDeclId<T> {
56    fn eq(&self, other: &Self) -> bool {
57        self.0.eq(&other.0)
58    }
59}
60
61impl<T> EqWithEngines for ParsedDeclId<T> {}
62impl<T> PartialEqWithEngines for ParsedDeclId<T> {
63    fn eq(&self, other: &Self, _ctx: &PartialEqWithEnginesContext) -> bool {
64        self.0 == other.0
65    }
66}
67
68impl<T> Hash for ParsedDeclId<T> {
69    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
70        self.0.hash(state)
71    }
72}
73
74impl<T> HashWithEngines for ParsedDeclId<T>
75where
76    ParsedDeclEngine: ParsedDeclEngineIndex<T>,
77    T: Named + Spanned + HashWithEngines,
78{
79    fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
80        let decl_engine = engines.pe();
81        let decl = decl_engine.get(self);
82        decl.name().hash(state);
83        decl.hash(state, engines);
84    }
85}
86
87impl<T> PartialOrd for ParsedDeclId<T> {
88    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
89        Some(self.cmp(other))
90    }
91}
92impl<T> Ord for ParsedDeclId<T> {
93    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
94        self.0.cmp(&other.0)
95    }
96}
97
98impl<T> Serialize for ParsedDeclId<T> {
99    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
100    where
101        S: serde::Serializer,
102    {
103        self.0.serialize(serializer)
104    }
105}
106
107impl<'de, T> Deserialize<'de> for ParsedDeclId<T> {
108    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
109    where
110        D: serde::Deserializer<'de>,
111    {
112        let id = usize::deserialize(deserializer)?;
113        Ok(ParsedDeclId::new(id))
114    }
115}
116
117impl<T> ParsedDeclId<T> {
118    pub(crate) fn new(id: usize) -> Self {
119        ParsedDeclId(id, PhantomData)
120    }
121
122    #[allow(dead_code)]
123    pub(crate) fn replace_id(&mut self, index: Self) {
124        self.0 = index.0;
125    }
126
127    #[allow(dead_code)]
128    pub(crate) fn dummy() -> Self {
129        // we assume that `usize::MAX` id is not possible in practice
130        Self(usize::MAX, PhantomData)
131    }
132}
133
134#[allow(clippy::from_over_into)]
135impl<T> Into<usize> for ParsedDeclId<T> {
136    fn into(self) -> usize {
137        self.0
138    }
139}