1use std::{result::Result, sync::Arc};
9
10use crate::sync::*;
11use crate::types::status_code::StatusCode;
12use crate::types::{
13 AttributeId, DataValue, NodeId, NumericRange, QualifiedName, TimestampsToReturn,
14};
15
16use super::callbacks::{AttributeGetter, AttributeSetter};
17
18pub use self::address_space::AddressSpace;
19
20pub struct AttrFnGetter<F>
22where
23 F: FnMut(
24 &NodeId,
25 TimestampsToReturn,
26 AttributeId,
27 NumericRange,
28 &QualifiedName,
29 f64,
30 ) -> Result<Option<DataValue>, StatusCode>
31 + Send,
32{
33 getter: F,
34}
35
36impl<F> AttributeGetter for AttrFnGetter<F>
37where
38 F: FnMut(
39 &NodeId,
40 TimestampsToReturn,
41 AttributeId,
42 NumericRange,
43 &QualifiedName,
44 f64,
45 ) -> Result<Option<DataValue>, StatusCode>
46 + Send,
47{
48 fn get(
49 &mut self,
50 node_id: &NodeId,
51 timestamps_to_return: TimestampsToReturn,
52 attribute_id: AttributeId,
53 index_range: NumericRange,
54 data_encoding: &QualifiedName,
55 max_age: f64,
56 ) -> Result<Option<DataValue>, StatusCode> {
57 (self.getter)(
58 node_id,
59 timestamps_to_return,
60 attribute_id,
61 index_range,
62 data_encoding,
63 max_age,
64 )
65 }
66}
67
68impl<F> AttrFnGetter<F>
69where
70 F: FnMut(
71 &NodeId,
72 TimestampsToReturn,
73 AttributeId,
74 NumericRange,
75 &QualifiedName,
76 f64,
77 ) -> Result<Option<DataValue>, StatusCode>
78 + Send,
79{
80 pub fn new(getter: F) -> AttrFnGetter<F> {
81 AttrFnGetter { getter }
82 }
83
84 pub fn new_boxed(getter: F) -> Arc<Mutex<AttrFnGetter<F>>> {
85 Arc::new(Mutex::new(Self::new(getter)))
86 }
87}
88
89pub struct AttrFnSetter<F>
91where
92 F: FnMut(&NodeId, AttributeId, NumericRange, DataValue) -> Result<(), StatusCode> + Send,
93{
94 setter: F,
95}
96
97impl<F> AttributeSetter for AttrFnSetter<F>
98where
99 F: FnMut(&NodeId, AttributeId, NumericRange, DataValue) -> Result<(), StatusCode> + Send,
100{
101 fn set(
102 &mut self,
103 node_id: &NodeId,
104 attribute_id: AttributeId,
105 index_range: NumericRange,
106 data_value: DataValue,
107 ) -> Result<(), StatusCode> {
108 (self.setter)(node_id, attribute_id, index_range, data_value)
109 }
110}
111
112impl<F> AttrFnSetter<F>
113where
114 F: FnMut(&NodeId, AttributeId, NumericRange, DataValue) -> Result<(), StatusCode> + Send,
115{
116 pub fn new(setter: F) -> AttrFnSetter<F> {
117 AttrFnSetter { setter }
118 }
119
120 pub fn new_boxed(setter: F) -> Arc<Mutex<AttrFnSetter<F>>> {
121 Arc::new(Mutex::new(Self::new(setter)))
122 }
123}
124
125macro_rules! node_builder_impl {
128 ( $node_builder_ty:ident, $node_ty:ident ) => {
129 use $crate::server::address_space::{
130 address_space::AddressSpace, references::ReferenceDirection,
131 };
132
133 pub struct $node_builder_ty {
136 node: $node_ty,
137 references: Vec<(NodeId, NodeId, ReferenceDirection)>,
138 }
139
140 impl $node_builder_ty {
141 pub fn new<T, S>(node_id: &NodeId, browse_name: T, display_name: S) -> Self
143 where
144 T: Into<QualifiedName>,
145 S: Into<LocalizedText>,
146 {
147 trace!("Creating a node using a builder, node id {}", node_id);
148 Self {
149 node: $node_ty::default(),
150 references: Vec::with_capacity(10),
151 }
152 .node_id(node_id.clone())
153 .browse_name(browse_name)
154 .display_name(display_name)
155 }
156
157 pub fn get_node_id(&self) -> NodeId {
158 self.node.node_id()
159 }
160
161 fn node_id(mut self, node_id: NodeId) -> Self {
162 let _ = self.node.base.set_node_id(node_id);
163 self
164 }
165
166 fn browse_name<V>(mut self, browse_name: V) -> Self
167 where
168 V: Into<QualifiedName>,
169 {
170 let _ = self.node.base.set_browse_name(browse_name);
171 self
172 }
173
174 fn display_name<V>(mut self, display_name: V) -> Self
175 where
176 V: Into<LocalizedText>,
177 {
178 self.node.set_display_name(display_name.into());
179 self
180 }
181
182 pub fn is_valid(&self) -> bool {
184 self.node.is_valid()
185 }
186
187 pub fn description<V>(mut self, description: V) -> Self
189 where
190 V: Into<LocalizedText>,
191 {
192 self.node.set_description(description.into());
193 self
194 }
195
196 pub fn reference<T>(
198 mut self,
199 node_id: T,
200 reference_type_id: ReferenceTypeId,
201 reference_direction: ReferenceDirection,
202 ) -> Self
203 where
204 T: Into<NodeId>,
205 {
206 self.references.push((
207 node_id.into(),
208 reference_type_id.into(),
209 reference_direction,
210 ));
211 self
212 }
213
214 pub fn organizes<T>(self, organizes_id: T) -> Self
216 where
217 T: Into<NodeId>,
218 {
219 self.reference(
220 organizes_id,
221 ReferenceTypeId::Organizes,
222 ReferenceDirection::Forward,
223 )
224 }
225
226 pub fn organized_by<T>(self, organized_by_id: T) -> Self
228 where
229 T: Into<NodeId>,
230 {
231 self.reference(
232 organized_by_id,
233 ReferenceTypeId::Organizes,
234 ReferenceDirection::Inverse,
235 )
236 }
237
238 pub fn build(self) -> $node_ty {
242 if self.is_valid() {
243 self.node
244 } else {
245 panic!(
246 "The node is not valid, node id = {:?}",
247 self.node.base.node_id()
248 );
249 }
250 }
251
252 pub fn insert(self, address_space: &mut AddressSpace) -> bool {
255 if self.is_valid() {
256 if !self.references.is_empty() {
257 let references = self
258 .references
259 .iter()
260 .map(|v| (&v.0, &v.1, v.2))
261 .collect::<Vec<_>>();
262 address_space.insert(self.node, Some(references.as_slice()))
263 } else {
264 address_space.insert::<$node_ty, ReferenceTypeId>(self.node, None)
265 }
266 } else {
267 panic!(
268 "The node is not valid, node id = {:?}",
269 self.node.base.node_id()
270 );
271 }
272 }
273 }
274 };
275}
276
277macro_rules! node_builder_impl_generates_event {
278 ( $node_builder_ty:ident ) => {
279 impl $node_builder_ty {
280 pub fn generates_event<T>(self, event_type: T) -> Self
281 where
282 T: Into<NodeId>,
283 {
284 self.reference(
285 event_type,
286 ReferenceTypeId::GeneratesEvent,
287 ReferenceDirection::Forward,
288 )
289 }
290 }
291 };
292}
293
294macro_rules! node_builder_impl_subtype {
295 ( $node_builder_ty:ident ) => {
296 impl $node_builder_ty {
297 pub fn subtype_of<T>(self, type_id: T) -> Self
298 where
299 T: Into<NodeId>,
300 {
301 self.reference(
302 type_id,
303 ReferenceTypeId::HasSubtype,
304 ReferenceDirection::Inverse,
305 )
306 }
307
308 pub fn has_subtype<T>(self, subtype_id: T) -> Self
309 where
310 T: Into<NodeId>,
311 {
312 self.reference(
313 subtype_id,
314 ReferenceTypeId::HasSubtype,
315 ReferenceDirection::Forward,
316 )
317 }
318 }
319 };
320}
321
322macro_rules! node_builder_impl_component_of {
323 ( $node_builder_ty:ident ) => {
324 impl $node_builder_ty {
325 pub fn component_of<T>(self, component_of_id: T) -> Self
326 where
327 T: Into<NodeId>,
328 {
329 self.reference(
330 component_of_id,
331 ReferenceTypeId::HasComponent,
332 ReferenceDirection::Inverse,
333 )
334 }
335
336 pub fn has_component<T>(self, has_component_id: T) -> Self
337 where
338 T: Into<NodeId>,
339 {
340 self.reference(
341 has_component_id,
342 ReferenceTypeId::HasComponent,
343 ReferenceDirection::Forward,
344 )
345 }
346 }
347 };
348}
349
350macro_rules! node_builder_impl_property_of {
351 ( $node_builder_ty:ident ) => {
352 impl $node_builder_ty {
353 pub fn has_property<T>(self, has_component_id: T) -> Self
354 where
355 T: Into<NodeId>,
356 {
357 self.reference(
358 has_component_id,
359 ReferenceTypeId::HasProperty,
360 ReferenceDirection::Forward,
361 )
362 }
363
364 pub fn property_of<T>(self, component_of_id: T) -> Self
365 where
366 T: Into<NodeId>,
367 {
368 self.reference(
369 component_of_id,
370 ReferenceTypeId::HasProperty,
371 ReferenceDirection::Inverse,
372 )
373 }
374 }
375 };
376}
377
378macro_rules! node_base_impl {
381 ( $node_struct:ident ) => {
382 use crate::{
383 server::address_space::node::NodeType,
384 types::{status_code::StatusCode, *},
385 };
386
387 impl Into<NodeType> for $node_struct {
388 fn into(self) -> NodeType {
389 NodeType::$node_struct(Box::new(self))
390 }
391 }
392
393 impl NodeBase for $node_struct {
394 fn node_class(&self) -> NodeClass {
395 self.base.node_class()
396 }
397
398 fn node_id(&self) -> NodeId {
399 self.base.node_id()
400 }
401
402 fn browse_name(&self) -> QualifiedName {
403 self.base.browse_name()
404 }
405
406 fn display_name(&self) -> LocalizedText {
407 self.base.display_name()
408 }
409
410 fn set_display_name(&mut self, display_name: LocalizedText) {
411 self.base.set_display_name(display_name);
412 }
413
414 fn description(&self) -> Option<LocalizedText> {
415 self.base.description()
416 }
417
418 fn set_description(&mut self, description: LocalizedText) {
419 self.base.set_description(description);
420 }
421
422 fn write_mask(&self) -> Option<WriteMask> {
423 self.base.write_mask()
424 }
425
426 fn set_write_mask(&mut self, write_mask: WriteMask) {
427 self.base.set_write_mask(write_mask);
428 }
429
430 fn user_write_mask(&self) -> Option<WriteMask> {
431 self.base.user_write_mask()
432 }
433
434 fn set_user_write_mask(&mut self, user_write_mask: WriteMask) {
435 self.base.set_user_write_mask(user_write_mask)
436 }
437 }
438 };
439}
440
441pub mod address_space;
442pub mod base;
443pub mod data_type;
444pub mod method;
445pub mod node;
446pub mod object;
447pub mod object_type;
448pub mod reference_type;
449pub mod references;
450pub mod relative_path;
451pub mod variable;
452pub mod variable_type;
453pub mod view;
454
455#[rustfmt::skip]
456#[cfg(feature = "generated-address-space")]
457mod generated;
458#[cfg(feature = "generated-address-space")]
459mod method_impls;
460
461bitflags! {
462 pub struct AccessLevel: u8 {
463 const CURRENT_READ = 1;
464 const CURRENT_WRITE = 2;
465 const HISTORY_READ = 4;
466 const HISTORY_WRITE = 8;
467 }
472}
473
474bitflags! {
475 pub struct UserAccessLevel: u8 {
476 const CURRENT_READ = 1;
477 const CURRENT_WRITE = 2;
478 const HISTORY_READ = 4;
479 const HISTORY_WRITE = 8;
480 }
484}
485
486bitflags! {
487 pub struct EventNotifier: u8 {
488 const SUBSCRIBE_TO_EVENTS = 1;
489 const HISTORY_READ = 4;
490 const HISTORY_WRITE = 8;
491 }
492}
493
494pub mod types {
495 pub use super::address_space::AddressSpace;
496 pub use super::data_type::{DataType, DataTypeBuilder};
497 pub use super::method::{Method, MethodBuilder};
498 pub use super::node::{NodeBase, NodeType};
499 pub use super::object::{Object, ObjectBuilder};
500 pub use super::object_type::{ObjectType, ObjectTypeBuilder};
501 pub use super::reference_type::{ReferenceType, ReferenceTypeBuilder};
502 pub use super::references::ReferenceDirection;
503 pub use super::variable::{Variable, VariableBuilder};
504 pub use super::variable_type::{VariableType, VariableTypeBuilder};
505 pub use super::view::{View, ViewBuilder};
506 pub use super::{AttrFnGetter, AttrFnSetter};
507}