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}