cameleon_genapi/
node_base.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 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    /// `pInvalidator` works only for `Register` kind nodes. It is not used in this crate.
133    /// See https://github.com/cameleon-rs/cameleon/issues/138 for more details.
134    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}