Skip to main content

trellis_core/
node.rs

1use crate::{DependencyList, NodeId, Revision, ScopeId};
2use core::any::TypeId;
3use core::marker::PhantomData;
4
5/// The metadata kind of a graph node.
6#[derive(Copy, Clone, Debug, Eq, PartialEq)]
7pub enum NodeKind {
8    /// Canonical input supplied by the host.
9    Input,
10    /// Value derived from declared dependencies.
11    Derived,
12    /// Collection derived from declared dependencies.
13    Collection,
14}
15
16/// Common behavior for typed node handles.
17pub trait NodeHandle {
18    /// Returns the graph-local node id backing this typed handle.
19    fn id(self) -> NodeId;
20}
21
22/// Typed handle for an input node.
23#[derive(Debug, Eq, PartialEq, Hash)]
24pub struct InputNode<T> {
25    id: NodeId,
26    _marker: PhantomData<fn() -> T>,
27}
28
29impl<T> InputNode<T> {
30    pub(crate) fn new(id: NodeId) -> Self {
31        Self {
32            id,
33            _marker: PhantomData,
34        }
35    }
36
37    /// Returns the graph-local node id.
38    pub fn id(&self) -> NodeId {
39        self.id
40    }
41}
42
43impl<T> Copy for InputNode<T> {}
44
45impl<T> Clone for InputNode<T> {
46    fn clone(&self) -> Self {
47        *self
48    }
49}
50
51impl<T> NodeHandle for InputNode<T> {
52    fn id(self) -> NodeId {
53        self.id
54    }
55}
56
57/// Typed handle for a derived node.
58#[derive(Debug, Eq, PartialEq, Hash)]
59pub struct DerivedNode<T> {
60    id: NodeId,
61    _marker: PhantomData<fn() -> T>,
62}
63
64impl<T> DerivedNode<T> {
65    pub(crate) fn new(id: NodeId) -> Self {
66        Self {
67            id,
68            _marker: PhantomData,
69        }
70    }
71
72    /// Returns the graph-local node id.
73    pub fn id(&self) -> NodeId {
74        self.id
75    }
76}
77
78impl<T> Copy for DerivedNode<T> {}
79
80impl<T> Clone for DerivedNode<T> {
81    fn clone(&self) -> Self {
82        *self
83    }
84}
85
86impl<T> NodeHandle for DerivedNode<T> {
87    fn id(self) -> NodeId {
88        self.id
89    }
90}
91
92/// Typed handle for a collection node.
93#[derive(Debug, Eq, PartialEq, Hash)]
94pub struct CollectionNode<K, V> {
95    id: NodeId,
96    _marker: PhantomData<fn() -> (K, V)>,
97}
98
99impl<K, V> CollectionNode<K, V> {
100    pub(crate) fn new(id: NodeId) -> Self {
101        Self {
102            id,
103            _marker: PhantomData,
104        }
105    }
106
107    /// Returns the graph-local node id.
108    pub fn id(&self) -> NodeId {
109        self.id
110    }
111}
112
113impl<K, V> Copy for CollectionNode<K, V> {}
114
115impl<K, V> Clone for CollectionNode<K, V> {
116    fn clone(&self) -> Self {
117        *self
118    }
119}
120
121impl<K, V> NodeHandle for CollectionNode<K, V> {
122    fn id(self) -> NodeId {
123        self.id
124    }
125}
126
127/// Inspectable metadata for a graph node.
128#[derive(Clone, Debug, Eq, PartialEq)]
129pub struct NodeMeta {
130    id: NodeId,
131    kind: NodeKind,
132    debug_name: String,
133    dependencies: DependencyList,
134    owning_scope: Option<ScopeId>,
135    created_revision: Revision,
136    last_changed_revision: Revision,
137    value_type: Option<TypeId>,
138}
139
140impl NodeMeta {
141    pub(crate) fn new(
142        id: NodeId,
143        kind: NodeKind,
144        debug_name: impl Into<String>,
145        dependencies: DependencyList,
146        created_revision: Revision,
147        value_type: Option<TypeId>,
148    ) -> Self {
149        Self {
150            id,
151            kind,
152            debug_name: debug_name.into(),
153            dependencies,
154            owning_scope: None,
155            created_revision,
156            last_changed_revision: created_revision,
157            value_type,
158        }
159    }
160
161    /// Returns this node's id.
162    pub fn id(&self) -> NodeId {
163        self.id
164    }
165
166    /// Returns this node's kind.
167    pub fn kind(&self) -> NodeKind {
168        self.kind
169    }
170
171    /// Returns this node's debug name.
172    pub fn debug_name(&self) -> &str {
173        &self.debug_name
174    }
175
176    /// Returns this node's declared dependencies.
177    pub fn dependencies(&self) -> &DependencyList {
178        &self.dependencies
179    }
180
181    /// Returns this node's owning scope, if one has been attached.
182    pub fn owning_scope(&self) -> Option<ScopeId> {
183        self.owning_scope
184    }
185
186    /// Returns the graph revision at which this node was created.
187    pub fn created_revision(&self) -> Revision {
188        self.created_revision
189    }
190
191    /// Returns the graph revision at which this node last changed.
192    pub fn last_changed_revision(&self) -> Revision {
193        self.last_changed_revision
194    }
195
196    pub(crate) fn attach_scope(&mut self, scope: ScopeId) {
197        self.owning_scope = Some(scope);
198    }
199
200    pub(crate) fn detach_scope(&mut self, scope: ScopeId) {
201        if self.owning_scope == Some(scope) {
202            self.owning_scope = None;
203        }
204    }
205
206    pub(crate) fn value_type(&self) -> Option<TypeId> {
207        self.value_type
208    }
209
210    pub(crate) fn mark_changed(&mut self, revision: Revision) {
211        self.last_changed_revision = revision;
212    }
213
214    pub(crate) fn mark_created(&mut self, revision: Revision) {
215        self.created_revision = revision;
216        self.last_changed_revision = revision;
217    }
218}