cameleon_genapi/
interface.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use ambassador::{delegatable_trait, Delegate};
6
7use super::{
8    elem_type::{DisplayNotation, FloatRepresentation, IntegerRepresentation},
9    node_base::NodeBase,
10    store::{CacheStore, NodeData, NodeId, NodeStore, ValueStore},
11    {Device, GenApiResult, ValueCtxt},
12};
13
14#[derive(Clone, Debug)]
15pub enum IncrementMode {
16    FixedIncrement,
17    /// NOTE: `ListIncrement` is not supported in `GenApiSchema Version 1.1` yet.
18    ListIncrement,
19}
20
21#[delegatable_trait]
22pub trait INode {
23    fn name<'s>(&self, store: &'s impl NodeStore) -> &'s str {
24        store.name_by_id(self.node_base().id()).unwrap()
25    }
26
27    fn node_base(&self) -> NodeBase;
28    fn streamable(&self) -> bool;
29}
30
31#[delegatable_trait]
32pub trait IInteger {
33    fn value<T: ValueStore, U: CacheStore>(
34        &self,
35        device: &mut impl Device,
36        store: &impl NodeStore,
37        cx: &mut ValueCtxt<T, U>,
38    ) -> GenApiResult<i64>;
39
40    fn set_value<T: ValueStore, U: CacheStore>(
41        &self,
42        value: i64,
43        device: &mut impl Device,
44        store: &impl NodeStore,
45        cx: &mut ValueCtxt<T, U>,
46    ) -> GenApiResult<()>;
47
48    fn min<T: ValueStore, U: CacheStore>(
49        &self,
50        device: &mut impl Device,
51        store: &impl NodeStore,
52        cx: &mut ValueCtxt<T, U>,
53    ) -> GenApiResult<i64>;
54
55    fn max<T: ValueStore, U: CacheStore>(
56        &self,
57        device: &mut impl Device,
58        store: &impl NodeStore,
59        cx: &mut ValueCtxt<T, U>,
60    ) -> GenApiResult<i64>;
61
62    fn inc_mode(&self, store: &impl NodeStore) -> Option<IncrementMode>;
63
64    fn inc<T: ValueStore, U: CacheStore>(
65        &self,
66        device: &mut impl Device,
67        store: &impl NodeStore,
68        cx: &mut ValueCtxt<T, U>,
69    ) -> GenApiResult<Option<i64>>;
70
71    /// NOTE: `ValidValueSet` is not supported in `GenApiSchema Version 1.1` yet.
72    fn valid_value_set(&self, store: &impl NodeStore) -> &[i64];
73
74    fn representation(&self, store: &impl NodeStore) -> IntegerRepresentation;
75
76    fn unit(&self, store: &impl NodeStore) -> Option<&str>;
77
78    fn set_min<T: ValueStore, U: CacheStore>(
79        &self,
80        value: i64,
81        device: &mut impl Device,
82        store: &impl NodeStore,
83        cx: &mut ValueCtxt<T, U>,
84    ) -> GenApiResult<()>;
85
86    fn set_max<T: ValueStore, U: CacheStore>(
87        &self,
88        value: i64,
89        device: &mut impl Device,
90        store: &impl NodeStore,
91        cx: &mut ValueCtxt<T, U>,
92    ) -> GenApiResult<()>;
93
94    fn is_readable<T: ValueStore, U: CacheStore>(
95        &self,
96        device: &mut impl Device,
97        store: &impl NodeStore,
98        cx: &mut ValueCtxt<T, U>,
99    ) -> GenApiResult<bool>;
100
101    fn is_writable<T: ValueStore, U: CacheStore>(
102        &self,
103        device: &mut impl Device,
104        store: &impl NodeStore,
105        cx: &mut ValueCtxt<T, U>,
106    ) -> GenApiResult<bool>;
107}
108
109#[delegatable_trait]
110pub trait IFloat {
111    fn value<T: ValueStore, U: CacheStore>(
112        &self,
113        device: &mut impl Device,
114        store: &impl NodeStore,
115        cx: &mut ValueCtxt<T, U>,
116    ) -> GenApiResult<f64>;
117
118    fn set_value<T: ValueStore, U: CacheStore>(
119        &self,
120        value: f64,
121        device: &mut impl Device,
122        store: &impl NodeStore,
123        cx: &mut ValueCtxt<T, U>,
124    ) -> GenApiResult<()>;
125
126    fn min<T: ValueStore, U: CacheStore>(
127        &self,
128        device: &mut impl Device,
129        store: &impl NodeStore,
130        cx: &mut ValueCtxt<T, U>,
131    ) -> GenApiResult<f64>;
132
133    fn max<T: ValueStore, U: CacheStore>(
134        &self,
135        device: &mut impl Device,
136        store: &impl NodeStore,
137        cx: &mut ValueCtxt<T, U>,
138    ) -> GenApiResult<f64>;
139
140    fn inc_mode(&self, store: &impl NodeStore) -> Option<IncrementMode>;
141
142    fn inc<T: ValueStore, U: CacheStore>(
143        &self,
144        device: &mut impl Device,
145        store: &impl NodeStore,
146        cx: &mut ValueCtxt<T, U>,
147    ) -> GenApiResult<Option<f64>>;
148
149    fn representation(&self, store: &impl NodeStore) -> FloatRepresentation;
150
151    fn unit(&self, store: &impl NodeStore) -> Option<&str>;
152
153    fn display_notation(&self, store: &impl NodeStore) -> DisplayNotation;
154
155    fn display_precision(&self, store: &impl NodeStore) -> i64;
156
157    fn set_min<T: ValueStore, U: CacheStore>(
158        &self,
159        value: f64,
160        device: &mut impl Device,
161        store: &impl NodeStore,
162        cx: &mut ValueCtxt<T, U>,
163    ) -> GenApiResult<()>;
164
165    fn set_max<T: ValueStore, U: CacheStore>(
166        &self,
167        value: f64,
168        device: &mut impl Device,
169        store: &impl NodeStore,
170        cx: &mut ValueCtxt<T, U>,
171    ) -> GenApiResult<()>;
172
173    fn is_readable<T: ValueStore, U: CacheStore>(
174        &self,
175        device: &mut impl Device,
176        store: &impl NodeStore,
177        cx: &mut ValueCtxt<T, U>,
178    ) -> GenApiResult<bool>;
179
180    fn is_writable<T: ValueStore, U: CacheStore>(
181        &self,
182        device: &mut impl Device,
183        store: &impl NodeStore,
184        cx: &mut ValueCtxt<T, U>,
185    ) -> GenApiResult<bool>;
186}
187
188#[delegatable_trait]
189pub trait IString {
190    fn value<T: ValueStore, U: CacheStore>(
191        &self,
192        device: &mut impl Device,
193        store: &impl NodeStore,
194        cx: &mut ValueCtxt<T, U>,
195    ) -> GenApiResult<String>;
196
197    fn set_value<T: ValueStore, U: CacheStore>(
198        &self,
199        value: String,
200        device: &mut impl Device,
201        store: &impl NodeStore,
202        cx: &mut ValueCtxt<T, U>,
203    ) -> GenApiResult<()>;
204
205    fn max_length<T: ValueStore, U: CacheStore>(
206        &self,
207        device: &mut impl Device,
208        store: &impl NodeStore,
209        cx: &mut ValueCtxt<T, U>,
210    ) -> GenApiResult<i64>;
211
212    fn is_readable<T: ValueStore, U: CacheStore>(
213        &self,
214        device: &mut impl Device,
215        store: &impl NodeStore,
216        cx: &mut ValueCtxt<T, U>,
217    ) -> GenApiResult<bool>;
218
219    fn is_writable<T: ValueStore, U: CacheStore>(
220        &self,
221        device: &mut impl Device,
222        store: &impl NodeStore,
223        cx: &mut ValueCtxt<T, U>,
224    ) -> GenApiResult<bool>;
225}
226
227#[delegatable_trait]
228pub trait IEnumeration {
229    fn current_value<T: ValueStore, U: CacheStore>(
230        &self,
231        device: &mut impl Device,
232        store: &impl NodeStore,
233        cx: &mut ValueCtxt<T, U>,
234    ) -> GenApiResult<i64>;
235
236    fn current_entry<T: ValueStore, U: CacheStore>(
237        &self,
238        device: &mut impl Device,
239        store: &impl NodeStore,
240        cx: &mut ValueCtxt<T, U>,
241    ) -> GenApiResult<NodeId>;
242
243    fn entries(&self, store: &impl NodeStore) -> &[NodeId];
244
245    /// Get [`NodeId`] of enum entry which has specified symbolic name.
246    fn entry_by_symbolic(&self, name: &str, store: &impl NodeStore) -> Option<NodeId> {
247        for nid in self.entries(store) {
248            let ent = nid.expect_enum_entry(store).unwrap(); // Never fail when parse is succeeded.
249            if ent.symbolic() == name {
250                return Some(*nid);
251            }
252        }
253        None
254    }
255
256    fn set_entry_by_symbolic<T: ValueStore, U: CacheStore>(
257        &self,
258        name: &str,
259        device: &mut impl Device,
260        store: &impl NodeStore,
261        cx: &mut ValueCtxt<T, U>,
262    ) -> GenApiResult<()>;
263
264    fn set_entry_by_value<T: ValueStore, U: CacheStore>(
265        &self,
266        value: i64,
267        device: &mut impl Device,
268        store: &impl NodeStore,
269        cx: &mut ValueCtxt<T, U>,
270    ) -> GenApiResult<()>;
271
272    fn is_readable<T: ValueStore, U: CacheStore>(
273        &self,
274        device: &mut impl Device,
275        store: &impl NodeStore,
276        cx: &mut ValueCtxt<T, U>,
277    ) -> GenApiResult<bool>;
278
279    fn is_writable<T: ValueStore, U: CacheStore>(
280        &self,
281        device: &mut impl Device,
282        store: &impl NodeStore,
283        cx: &mut ValueCtxt<T, U>,
284    ) -> GenApiResult<bool>;
285}
286
287#[delegatable_trait]
288pub trait ICommand {
289    fn execute<T: ValueStore, U: CacheStore>(
290        &self,
291        device: &mut impl Device,
292        store: &impl NodeStore,
293        cx: &mut ValueCtxt<T, U>,
294    ) -> GenApiResult<()>;
295
296    fn is_done<T: ValueStore, U: CacheStore>(
297        &self,
298        device: &mut impl Device,
299        store: &impl NodeStore,
300        cx: &mut ValueCtxt<T, U>,
301    ) -> GenApiResult<bool>;
302
303    fn is_writable<T: ValueStore, U: CacheStore>(
304        &self,
305        device: &mut impl Device,
306        store: &impl NodeStore,
307        cx: &mut ValueCtxt<T, U>,
308    ) -> GenApiResult<bool>;
309}
310
311#[delegatable_trait]
312pub trait IBoolean {
313    fn value<T: ValueStore, U: CacheStore>(
314        &self,
315        device: &mut impl Device,
316        store: &impl NodeStore,
317        cx: &mut ValueCtxt<T, U>,
318    ) -> GenApiResult<bool>;
319
320    fn set_value<T: ValueStore, U: CacheStore>(
321        &self,
322        value: bool,
323        device: &mut impl Device,
324        store: &impl NodeStore,
325        cx: &mut ValueCtxt<T, U>,
326    ) -> GenApiResult<()>;
327
328    fn is_readable<T: ValueStore, U: CacheStore>(
329        &self,
330        device: &mut impl Device,
331        store: &impl NodeStore,
332        cx: &mut ValueCtxt<T, U>,
333    ) -> GenApiResult<bool>;
334
335    fn is_writable<T: ValueStore, U: CacheStore>(
336        &self,
337        device: &mut impl Device,
338        store: &impl NodeStore,
339        cx: &mut ValueCtxt<T, U>,
340    ) -> GenApiResult<bool>;
341}
342
343#[delegatable_trait]
344pub trait IRegister {
345    /// Read bytes from the register.
346    ///
347    /// `buf.len()` must be same as the register length returned from [`IRegister::length`].
348    fn read<T: ValueStore, U: CacheStore>(
349        &self,
350        buf: &mut [u8],
351        device: &mut impl Device,
352        store: &impl NodeStore,
353        cx: &mut ValueCtxt<T, U>,
354    ) -> GenApiResult<()>;
355
356    /// Write bytes to the register.
357    ///
358    /// `buf.len()` must be same as the register length returned from [`IRegister::length`].
359    fn write<T: ValueStore, U: CacheStore>(
360        &self,
361        buf: &[u8],
362        device: &mut impl Device,
363        store: &impl NodeStore,
364        cx: &mut ValueCtxt<T, U>,
365    ) -> GenApiResult<()>;
366
367    fn address<T: ValueStore, U: CacheStore>(
368        &self,
369        device: &mut impl Device,
370        store: &impl NodeStore,
371        cx: &mut ValueCtxt<T, U>,
372    ) -> GenApiResult<i64>;
373
374    fn length<T: ValueStore, U: CacheStore>(
375        &self,
376        device: &mut impl Device,
377        store: &impl NodeStore,
378        cx: &mut ValueCtxt<T, U>,
379    ) -> GenApiResult<i64>;
380}
381
382#[delegatable_trait]
383pub trait ICategory {
384    /// Return nodes in the category.
385    fn nodes(&self, store: &impl NodeStore) -> &[NodeId];
386}
387
388#[delegatable_trait]
389pub trait IPort {
390    fn read<T: ValueStore, U: CacheStore>(
391        &self,
392        address: i64,
393        buf: &mut [u8],
394        device: &mut impl Device,
395        store: &impl NodeStore,
396        cx: &mut ValueCtxt<T, U>,
397    ) -> GenApiResult<()>;
398
399    fn write<T: ValueStore, U: CacheStore>(
400        &self,
401        address: i64,
402        buf: &[u8],
403        device: &mut impl Device,
404        store: &impl NodeStore,
405        cx: &mut ValueCtxt<T, U>,
406    ) -> GenApiResult<()>;
407}
408
409#[delegatable_trait]
410pub trait ISelector {
411    /// Return nodes which refer to the current node as a selector.
412    fn selecting_nodes(&self, store: &impl NodeStore) -> GenApiResult<&[NodeId]>;
413}
414
415#[derive(Delegate, Clone, Copy, Debug)]
416#[delegate(INode)]
417pub enum INodeKind<'a> {
418    Integer(&'a super::IntegerNode),
419    IntReg(&'a super::IntRegNode),
420    MaskedIntReg(&'a super::MaskedIntRegNode),
421    IntConverter(&'a super::IntConverterNode),
422    IntSwissKnife(&'a super::IntSwissKnifeNode),
423    Float(&'a super::FloatNode),
424    FloatReg(&'a super::FloatRegNode),
425    Converter(&'a super::ConverterNode),
426    SwissKnife(&'a super::SwissKnifeNode),
427    String(&'a super::StringNode),
428    StringReg(&'a super::StringRegNode),
429    Boolean(&'a super::BooleanNode),
430    Command(&'a super::CommandNode),
431    Register(&'a super::RegisterNode),
432    Category(&'a super::CategoryNode),
433    Port(&'a super::PortNode),
434    Enumeration(&'a super::EnumerationNode),
435    EnumEntry(&'a super::EnumEntryNode),
436    Node(&'a super::Node),
437}
438
439impl<'a> INodeKind<'a> {
440    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
441        match store.node_opt(id)? {
442            NodeData::Integer(n) => Some(Self::Integer(n)),
443            NodeData::IntReg(n) => Some(Self::IntReg(n)),
444            NodeData::MaskedIntReg(n) => Some(Self::MaskedIntReg(n)),
445            NodeData::IntConverter(n) => Some(Self::IntConverter(n)),
446            NodeData::IntSwissKnife(n) => Some(Self::IntSwissKnife(n)),
447            NodeData::Float(n) => Some(Self::Float(n)),
448            NodeData::FloatReg(n) => Some(Self::FloatReg(n)),
449            NodeData::Converter(n) => Some(Self::Converter(n)),
450            NodeData::SwissKnife(n) => Some(Self::SwissKnife(n)),
451            NodeData::String(n) => Some(Self::String(n)),
452            NodeData::StringReg(n) => Some(Self::StringReg(n)),
453            NodeData::Boolean(n) => Some(Self::Boolean(n)),
454            NodeData::Command(n) => Some(Self::Command(n)),
455            NodeData::Register(n) => Some(Self::Register(n)),
456            NodeData::Category(n) => Some(Self::Category(n)),
457            NodeData::Port(n) => Some(Self::Port(n)),
458            NodeData::Enumeration(n) => Some(Self::Enumeration(n)),
459            NodeData::EnumEntry(n) => Some(Self::EnumEntry(n)),
460            NodeData::Node(n) => Some(Self::Node(n)),
461            _ => None,
462        }
463    }
464
465    /// Returns [`NodeBase`] with more precise lifetime.
466    pub fn node_base_precise(self) -> NodeBase<'a> {
467        match self {
468            Self::Integer(n) => n.node_base(),
469            Self::IntReg(n) => n.node_base(),
470            Self::MaskedIntReg(n) => n.node_base(),
471            Self::IntConverter(n) => n.node_base(),
472            Self::IntSwissKnife(n) => n.node_base(),
473            Self::Float(n) => n.node_base(),
474            Self::FloatReg(n) => n.node_base(),
475            Self::Converter(n) => n.node_base(),
476            Self::SwissKnife(n) => n.node_base(),
477            Self::String(n) => n.node_base(),
478            Self::StringReg(n) => n.node_base(),
479            Self::Boolean(n) => n.node_base(),
480            Self::Command(n) => n.node_base(),
481            Self::Register(n) => n.node_base(),
482            Self::Category(n) => n.node_base(),
483            Self::Port(n) => n.node_base(),
484            Self::Enumeration(n) => n.node_base(),
485            Self::EnumEntry(n) => n.node_base(),
486            Self::Node(n) => n.node_base(),
487        }
488    }
489}
490
491#[derive(Delegate, Clone, Copy, Debug)]
492#[delegate(IInteger)]
493pub enum IIntegerKind<'a> {
494    Integer(&'a super::IntegerNode),
495    IntReg(&'a super::IntRegNode),
496    MaskedIntReg(&'a super::MaskedIntRegNode),
497    IntConverter(&'a super::IntConverterNode),
498    IntSwissKnife(&'a super::IntSwissKnifeNode),
499}
500
501impl<'a> IIntegerKind<'a> {
502    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
503        match store.node_opt(id)? {
504            NodeData::Integer(n) => Some(Self::Integer(n)),
505            NodeData::IntReg(n) => Some(Self::IntReg(n)),
506            NodeData::MaskedIntReg(n) => Some(Self::MaskedIntReg(n)),
507            NodeData::IntConverter(n) => Some(Self::IntConverter(n)),
508            NodeData::IntSwissKnife(n) => Some(Self::IntSwissKnife(n)),
509            _ => None,
510        }
511    }
512}
513
514#[derive(Delegate, Clone, Copy, Debug)]
515#[delegate(IFloat)]
516pub enum IFloatKind<'a> {
517    Float(&'a super::FloatNode),
518    FloatReg(&'a super::FloatRegNode),
519    Converter(&'a super::ConverterNode),
520    SwissKnife(&'a super::SwissKnifeNode),
521}
522
523impl<'a> IFloatKind<'a> {
524    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
525        match store.node_opt(id)? {
526            NodeData::Float(n) => Some(Self::Float(n)),
527            NodeData::FloatReg(n) => Some(Self::FloatReg(n)),
528            NodeData::Converter(n) => Some(Self::Converter(n)),
529            NodeData::SwissKnife(n) => Some(Self::SwissKnife(n)),
530            _ => None,
531        }
532    }
533}
534
535#[derive(Delegate, Clone, Copy, Debug)]
536#[delegate(IString)]
537pub enum IStringKind<'a> {
538    String(&'a super::StringNode),
539    StringReg(&'a super::StringRegNode),
540}
541
542impl<'a> IStringKind<'a> {
543    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
544        match store.node_opt(id)? {
545            NodeData::String(n) => Some(Self::String(n)),
546            NodeData::StringReg(n) => Some(Self::StringReg(n)),
547            _ => None,
548        }
549    }
550}
551
552#[derive(Delegate, Clone, Copy, Debug)]
553#[delegate(ICommand)]
554pub enum ICommandKind<'a> {
555    Command(&'a super::CommandNode),
556}
557
558impl<'a> ICommandKind<'a> {
559    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
560        match store.node_opt(id)? {
561            NodeData::Command(n) => Some(Self::Command(n)),
562            _ => None,
563        }
564    }
565}
566
567#[derive(Delegate, Clone, Copy, Debug)]
568#[delegate(IEnumeration)]
569pub enum IEnumerationKind<'a> {
570    Enumeration(&'a super::EnumerationNode),
571}
572
573impl<'a> IEnumerationKind<'a> {
574    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
575        match store.node_opt(id)? {
576            NodeData::Enumeration(n) => Some(Self::Enumeration(n)),
577            _ => None,
578        }
579    }
580}
581
582#[derive(Delegate, Clone, Copy, Debug)]
583#[delegate(IBoolean)]
584pub enum IBooleanKind<'a> {
585    Boolean(&'a super::BooleanNode),
586}
587
588impl<'a> IBooleanKind<'a> {
589    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
590        match store.node_opt(id)? {
591            NodeData::Boolean(n) => Some(Self::Boolean(n)),
592            _ => None,
593        }
594    }
595}
596
597#[derive(Delegate, Clone, Copy, Debug)]
598#[delegate(IRegister)]
599pub enum IRegisterKind<'a> {
600    Register(&'a super::RegisterNode),
601    IntReg(&'a super::IntRegNode),
602    MaskedIntReg(&'a super::MaskedIntRegNode),
603    StringReg(&'a super::StringRegNode),
604    FloatReg(&'a super::FloatRegNode),
605}
606
607impl<'a> IRegisterKind<'a> {
608    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
609        match store.node_opt(id)? {
610            NodeData::Register(n) => Some(Self::Register(n)),
611            NodeData::IntReg(n) => Some(Self::IntReg(n)),
612            NodeData::MaskedIntReg(n) => Some(Self::MaskedIntReg(n)),
613            NodeData::StringReg(n) => Some(Self::StringReg(n)),
614            NodeData::FloatReg(n) => Some(Self::FloatReg(n)),
615            _ => None,
616        }
617    }
618}
619
620#[derive(Delegate, Clone, Copy, Debug)]
621#[delegate(ICategory)]
622pub enum ICategoryKind<'a> {
623    Category(&'a super::CategoryNode),
624}
625
626impl<'a> ICategoryKind<'a> {
627    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
628        match store.node_opt(id)? {
629            NodeData::Category(n) => Some(Self::Category(n)),
630            _ => None,
631        }
632    }
633}
634
635#[derive(Delegate, Clone, Copy, Debug)]
636#[delegate(IPort)]
637pub enum IPortKind<'a> {
638    Port(&'a super::PortNode),
639}
640
641impl<'a> IPortKind<'a> {
642    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
643        match store.node_opt(id)? {
644            NodeData::Port(n) => Some(Self::Port(n)),
645            _ => None,
646        }
647    }
648}
649
650#[derive(Delegate, Clone, Copy, Debug)]
651#[delegate(ISelector)]
652pub enum ISelectorKind<'a> {
653    Integer(&'a super::IntegerNode),
654    IntReg(&'a super::IntRegNode),
655    MaskedIntReg(&'a super::MaskedIntRegNode),
656    Boolean(&'a super::BooleanNode),
657    Enumeration(&'a super::EnumerationNode),
658}
659
660impl<'a> ISelectorKind<'a> {
661    pub(super) fn maybe_from(id: NodeId, store: &'a impl NodeStore) -> Option<Self> {
662        match store.node_opt(id)? {
663            NodeData::Integer(n) => Some(Self::Integer(n)),
664            NodeData::IntReg(n) => Some(Self::IntReg(n)),
665            NodeData::MaskedIntReg(n) => Some(Self::MaskedIntReg(n)),
666            NodeData::Boolean(n) => Some(Self::Boolean(n)),
667            NodeData::Enumeration(n) => Some(Self::Enumeration(n)),
668            _ => None,
669        }
670    }
671}