surfer_translation_types/
variable_ref.rs

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