surfer_translation_types/
variable_ref.rs

1use crate::ScopeRef;
2#[cfg(feature = "wasm_plugins")]
3use extism_convert::{FromBytes, Json, ToBytes};
4use serde::{Deserialize, Serialize};
5use std::hash::{Hash, Hasher};
6
7// FIXME: We'll be cloning these quite a bit, I wonder if a `Cow<&str>` or Rc/Arc would be better
8#[cfg_attr(feature = "wasm_plugins", derive(FromBytes, ToBytes))]
9#[cfg_attr(feature = "wasm_plugins", encoding(Json))]
10#[derive(Clone, Debug, Eq, Serialize, Deserialize)]
11pub struct VariableRef<VarId, ScopeId> {
12    /// Path in the scope hierarchy to where this variable resides
13    pub path: ScopeRef<ScopeId>,
14    /// Name of the variable in its hierarchy
15    pub name: String,
16    /// Backend specific numeric ID. Performance optimization.
17    pub id: VarId,
18}
19
20impl<VarId, ScopeId> VariableRef<VarId, ScopeId> {
21    pub fn map_ids<VarId2, ScopeId2>(
22        self,
23        mut var_fn: impl FnMut(VarId) -> VarId2,
24        scope_fn: impl FnMut(ScopeId) -> ScopeId2,
25    ) -> VariableRef<VarId2, ScopeId2> {
26        VariableRef {
27            path: self.path.map_id(scope_fn),
28            name: self.name,
29            id: var_fn(self.id),
30        }
31    }
32
33    pub fn full_path(&self) -> Vec<String> {
34        self.path
35            .strs
36            .iter()
37            .cloned()
38            .chain([self.name.clone()])
39            .collect()
40    }
41}
42
43impl<VarId, ScopeId> AsRef<VariableRef<VarId, ScopeId>> for VariableRef<VarId, ScopeId> {
44    fn as_ref(&self) -> &VariableRef<VarId, ScopeId> {
45        self
46    }
47}
48
49impl<VarId, ScopeId> Hash for VariableRef<VarId, ScopeId> {
50    fn hash<H: Hasher>(&self, state: &mut H) {
51        // id is intentionally not hashed, since it is only a performance hint
52        self.path.hash(state);
53        self.name.hash(state);
54    }
55}
56
57impl<VarId, ScopeId> PartialEq for VariableRef<VarId, ScopeId> {
58    fn eq(&self, other: &Self) -> bool {
59        // id is intentionally not compared, since it is only a performance hint
60        self.path.eq(&other.path) && self.name.eq(&other.name)
61    }
62}