1use super::{
6 elem_type::{AccessMode, MergePriority, NameSpace, Visibility},
7 store::{CacheStore, NodeId, NodeStore, ValueStore},
8 utils::bool_from_id,
9 Device, GenApiResult, ValueCtxt,
10};
11
12pub struct NodeBase<'a> {
13 pub(crate) attr: &'a NodeAttributeBase,
14 pub(crate) elem: &'a NodeElementBase,
15}
16
17macro_rules! optional_string_elem_getter {
18 (
19 $(#[$meta:meta])*
20 $name:ident
21 ) => {
22 $(#[$meta])*
23 #[must_use] pub fn $name(&self) -> Option<&'a str> {
24 self.elem.$name.as_deref()
25 }
26 };
27}
28
29macro_rules! optional_node_id_elem_getter {
30 (
31 $(#[$meta:meta])*
32 $name:ident
33 ) => {
34 $(#[$meta])*
35 #[must_use] pub fn $name(&self) -> Option<NodeId> {
36 self.elem.$name
37 }
38 };
39}
40
41impl<'a> NodeBase<'a> {
42 pub(crate) fn new(attr: &'a NodeAttributeBase, elem: &'a NodeElementBase) -> Self {
43 Self { attr, elem }
44 }
45
46 #[must_use]
47 pub fn id(&self) -> NodeId {
48 self.attr.id
49 }
50
51 #[must_use]
52 pub fn name_space(&self) -> NameSpace {
53 self.attr.name_space
54 }
55
56 #[must_use]
57 pub fn merge_priority(&self) -> MergePriority {
58 self.attr.merge_priority
59 }
60
61 #[must_use]
62 pub fn expose_static(&self) -> Option<bool> {
63 self.attr.expose_static
64 }
65
66 #[must_use]
67 pub fn display_name(&self) -> Option<&'a str> {
68 self.elem.display_name.as_deref()
69 }
70
71 #[must_use]
72 pub fn visibility(&self) -> Visibility {
73 self.elem.visibility
74 }
75
76 #[must_use]
77 pub fn is_deprecated(&self) -> bool {
78 self.elem.is_deprecated
79 }
80
81 #[must_use]
82 pub fn imposed_access_mode(&self) -> AccessMode {
83 self.elem.imposed_access_mode
84 }
85
86 #[must_use]
87 pub fn p_errors(&self) -> &'a [NodeId] {
88 &self.elem.p_errors
89 }
90
91 #[must_use]
92 pub fn event_id(&self) -> Option<u64> {
93 self.elem.event_id
94 }
95
96 optional_string_elem_getter! {description}
97 optional_string_elem_getter! {tooltip}
98 optional_string_elem_getter! {docu_url}
99 optional_node_id_elem_getter! {p_is_implemented}
100 optional_node_id_elem_getter! {p_is_available}
101 optional_node_id_elem_getter! {p_is_locked}
102 optional_node_id_elem_getter! {p_block_polling}
103 optional_node_id_elem_getter! {p_alias}
104 optional_node_id_elem_getter! {p_cast_alias}
105}
106
107#[derive(Debug, Clone)]
108pub(crate) struct NodeAttributeBase {
109 pub(crate) id: NodeId,
110 pub(crate) name_space: NameSpace,
111 pub(crate) merge_priority: MergePriority,
112 pub(crate) expose_static: Option<bool>,
113}
114
115#[derive(Debug, Clone)]
116pub(crate) struct NodeElementBase {
117 pub(crate) tooltip: Option<String>,
118 pub(crate) description: Option<String>,
119 pub(crate) display_name: Option<String>,
120 pub(crate) visibility: Visibility,
121 pub(crate) docu_url: Option<String>,
122 pub(crate) is_deprecated: bool,
123 pub(crate) event_id: Option<u64>,
124 pub(crate) p_is_implemented: Option<NodeId>,
125 pub(crate) p_is_available: Option<NodeId>,
126 pub(crate) p_is_locked: Option<NodeId>,
127 pub(crate) p_block_polling: Option<NodeId>,
128 pub(crate) imposed_access_mode: AccessMode,
129 pub(crate) p_errors: Vec<NodeId>,
130 pub(crate) p_alias: Option<NodeId>,
131 pub(crate) p_cast_alias: Option<NodeId>,
132 pub(crate) p_invalidators: Vec<NodeId>,
135}
136
137impl NodeElementBase {
138 pub(super) fn is_readable<T: ValueStore, U: CacheStore>(
139 &self,
140 device: &mut impl Device,
141 store: &impl NodeStore,
142 cx: &mut ValueCtxt<T, U>,
143 ) -> GenApiResult<bool> {
144 Ok(self.is_implemented(device, store, cx)?
145 && self.is_available(device, store, cx)?
146 && matches!(self.imposed_access_mode, AccessMode::RO | AccessMode::RW))
147 }
148
149 pub(super) fn is_writable<T: ValueStore, U: CacheStore>(
150 &self,
151 device: &mut impl Device,
152 store: &impl NodeStore,
153 cx: &mut ValueCtxt<T, U>,
154 ) -> GenApiResult<bool> {
155 Ok(self.is_implemented(device, store, cx)?
156 && self.is_available(device, store, cx)?
157 && !self.is_locked(device, store, cx)?
158 && matches!(self.imposed_access_mode, AccessMode::WO | AccessMode::RW))
159 }
160
161 pub(super) fn is_locked<T: ValueStore, U: CacheStore>(
162 &self,
163 device: &mut impl Device,
164 store: &impl NodeStore,
165 cx: &mut ValueCtxt<T, U>,
166 ) -> GenApiResult<bool> {
167 self.p_is_locked
168 .map_or(Ok(false), |nid| bool_from_id(nid, device, store, cx))
169 }
170
171 pub(super) fn is_implemented<T: ValueStore, U: CacheStore>(
172 &self,
173 device: &mut impl Device,
174 store: &impl NodeStore,
175 cx: &mut ValueCtxt<T, U>,
176 ) -> GenApiResult<bool> {
177 self.p_is_implemented
178 .map_or(Ok(true), |nid| bool_from_id(nid, device, store, cx))
179 }
180
181 pub(super) fn is_available<T: ValueStore, U: CacheStore>(
182 &self,
183 device: &mut impl Device,
184 store: &impl NodeStore,
185 cx: &mut ValueCtxt<T, U>,
186 ) -> GenApiResult<bool> {
187 self.p_is_available
188 .map_or(Ok(true), |nid| bool_from_id(nid, device, store, cx))
189 }
190}