Skip to main content

geam_core/runtime/value/
external.rs

1use crate::host::ExternalPayloadLease;
2use crate::plan::ExternalType;
3use ecow::EcoString;
4
5#[derive(Clone)]
6pub struct ExternalValue {
7    type_: ExternalType,
8    identity: ExternalValueIdentity,
9    inspection: EcoString,
10    _lease: ExternalPayloadLease,
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub struct ExternalValueIdentity(u64);
15
16impl ExternalValue {
17    pub(crate) fn from_evaluated(
18        type_: ExternalType,
19        lease: ExternalPayloadLease,
20        inspection: EcoString,
21    ) -> Self {
22        Self {
23            type_,
24            identity: ExternalValueIdentity(lease.id()),
25            inspection,
26            _lease: lease,
27        }
28    }
29
30    pub fn type_(&self) -> &ExternalType {
31        &self.type_
32    }
33
34    pub fn identity(&self) -> ExternalValueIdentity {
35        self.identity
36    }
37
38    pub fn inspection(&self) -> &EcoString {
39        &self.inspection
40    }
41}
42
43impl PartialEq for ExternalValue {
44    fn eq(&self, other: &Self) -> bool {
45        self.identity == other.identity
46    }
47}
48
49impl std::fmt::Debug for ExternalValue {
50    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51        formatter
52            .debug_struct("ExternalValue")
53            .field("type_", &self.type_)
54            .field("identity", &self.identity)
55            .field("inspection", &self.inspection)
56            .finish_non_exhaustive()
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::ExternalValue;
63    use crate::host::HostExternalStore;
64    use crate::plan::{ExternalType, ExternalTypeName};
65
66    #[test]
67    fn opaque_external_value_exposes_identity_and_inspection_without_payload_access() {
68        let store = HostExternalStore::default();
69        let source_hash = |_: &crate::host::HostExternalHashing<'_>, value: &usize| *value as u64;
70        let inspect = |context: &crate::host::HostExternalInspection<'_>, value: &usize| {
71            let stored = crate::host::HostStoredValue::<num_bigint::BigInt>::new(
72                crate::runtime::StoredRuntimeValue::test_int((*value).into()),
73            );
74            format!("Resource({})", context.inspect_stored_value(&stored)).into()
75        };
76        let first = store.insert(7usize, |_, left, right| left == right, source_hash, inspect);
77        let second = store.insert(7usize, |_, left, right| left == right, source_hash, inspect);
78        let type_ = ExternalType::new(
79            ExternalTypeName::new("domain".into(), "domain/resource".into(), "Resource".into()),
80            Vec::new(),
81        );
82        let stored_equal =
83            |_: &crate::runtime::StoredRuntimeValue, _: &crate::runtime::StoredRuntimeValue| false;
84        let equality = crate::host::HostExternalEquality::new(&stored_equal);
85        let stored_hash = |_: &crate::runtime::StoredRuntimeValue| 17;
86        let stored_inspect = |_: &crate::runtime::StoredRuntimeValue| "7".into();
87        let hashing = crate::host::HostExternalHashing::new(&stored_hash);
88        let inspection = crate::host::HostExternalInspection::new(&stored_inspect);
89        assert!(first.source_equal(&equality, &second));
90        assert!(second.source_equal(&equality, &first));
91        assert_eq!(first.source_hash(&hashing), 7);
92        assert_eq!(first.inspection(&inspection), "Resource(7)");
93        assert_eq!(second.inspection(&inspection), "Resource(7)");
94        let first = ExternalValue::from_evaluated(type_.clone(), first, "Resource(7)".into());
95        let second = ExternalValue::from_evaluated(type_.clone(), second, "Resource(7)".into());
96        let cloned = first.clone();
97        let debug = format!("{first:?}");
98
99        assert_eq!(first.type_(), &type_);
100        assert_eq!(first.inspection(), "Resource(7)");
101        assert_eq!(first, cloned);
102        assert_ne!(first, second);
103        assert_eq!(first.identity(), cloned.identity());
104        assert!(debug.contains("ExternalValue"));
105        assert!(debug.contains("Resource(7)"));
106        assert!(!debug.contains("7usize"));
107    }
108}