Skip to main content

sim_kernel/
value.rs

1//! The [`Value`] contract: the universal runtime handle for every object.
2//!
3//! The kernel defines the value type and the [`RuntimeObject`] marker that
4//! every object satisfies; concrete object kinds are supplied by the libraries.
5
6use std::{
7    any::Any,
8    hash::{Hash, Hasher},
9    sync::Arc,
10};
11
12use crate::object::{Object, ObjectCompat};
13
14/// Marker trait every concrete runtime object satisfies.
15///
16/// The kernel requires that an object be an [`Object`], be [`ObjectCompat`],
17/// and be `Any + Send + Sync`; the blanket impl grants this trait to every
18/// type that meets those bounds. Libraries supply the concrete object kinds.
19pub trait RuntimeObject: Object + ObjectCompat + Any + Send + Sync {}
20
21impl<T> RuntimeObject for T where T: Object + ObjectCompat + Any + Send + Sync {}
22
23impl dyn RuntimeObject {
24    /// Attempts to downcast the object to a concrete type `T`.
25    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
26        self.as_any().downcast_ref::<T>()
27    }
28}
29
30/// The universal runtime handle for every object.
31///
32/// A [`Value`] is a reference-counted handle to a [`RuntimeObject`]; it is the
33/// object end of the data flow `tokens -> checked forms -> objects -> checked
34/// calls -> objects -> encoded forms`. Equality and hashing are by object
35/// identity (pointer), not by structural contents.
36///
37/// # Examples
38///
39/// ```
40/// # use sim_kernel::Value;
41/// # fn demo(value: Value) {
42/// // Every value exposes its object and that object's header.
43/// let header = value.header();
44/// let _same = value.object().header();
45/// let _ = header;
46/// # }
47/// ```
48#[derive(Clone)]
49pub struct Value(Arc<dyn RuntimeObject>);
50
51impl Value {
52    pub(crate) fn from_arc(value: Arc<dyn RuntimeObject>) -> Self {
53        Self(value)
54    }
55
56    /// Borrows the underlying runtime object.
57    pub fn object(&self) -> &(dyn RuntimeObject + 'static) {
58        self.0.as_ref()
59    }
60
61    /// Borrows the object's [`ObjectHeader`](crate::ObjectHeader).
62    pub fn header(&self) -> &crate::ObjectHeader {
63        self.object().header()
64    }
65}
66
67impl core::fmt::Debug for Value {
68    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
69        f.write_str("Value(..)")
70    }
71}
72
73impl PartialEq for Value {
74    fn eq(&self, other: &Self) -> bool {
75        Arc::ptr_eq(&self.0, &other.0)
76    }
77}
78
79impl Eq for Value {}
80
81impl Hash for Value {
82    fn hash<H: Hasher>(&self, state: &mut H) {
83        let ptr = Arc::as_ptr(&self.0) as *const ();
84        ptr.hash(state);
85    }
86}