Skip to main content

opcua/server/address_space/
node.rs

1// OPCUA for Rust
2// SPDX-License-Identifier: MPL-2.0
3// Copyright (C) 2017-2022 Adam Lock
4
5use crate::types::{
6    service_types::NodeClass, status_code::StatusCode, AttributeId, DataValue, LocalizedText,
7    NodeId, NumericRange, QualifiedName, TimestampsToReturn, Variant, WriteMask,
8};
9
10use super::types::{
11    DataType, Method, Object, ObjectType, ReferenceType, Variable, VariableType, View,
12};
13
14/// A `NodeType` is an enumeration holding every kind of node which can be hosted within the `AddressSpace`.
15#[derive(Debug)]
16pub enum NodeType {
17    Object(Box<Object>),
18    ObjectType(Box<ObjectType>),
19    ReferenceType(Box<ReferenceType>),
20    Variable(Box<Variable>),
21    VariableType(Box<VariableType>),
22    View(Box<View>),
23    DataType(Box<DataType>),
24    Method(Box<Method>),
25}
26
27pub trait HasNodeId {
28    fn node_id(&self) -> NodeId;
29}
30
31impl HasNodeId for NodeType {
32    fn node_id(&self) -> NodeId {
33        self.as_node().node_id()
34    }
35}
36
37impl NodeType {
38    pub fn as_node(&self) -> &dyn Node {
39        match self {
40            NodeType::Object(value) => value.as_ref(),
41            NodeType::ObjectType(value) => value.as_ref(),
42            NodeType::ReferenceType(value) => value.as_ref(),
43            NodeType::Variable(value) => value.as_ref(),
44            NodeType::VariableType(value) => value.as_ref(),
45            NodeType::View(value) => value.as_ref(),
46            NodeType::DataType(value) => value.as_ref(),
47            NodeType::Method(value) => value.as_ref(),
48        }
49    }
50
51    pub fn as_mut_node(&mut self) -> &mut dyn Node {
52        match self {
53            NodeType::Object(ref mut value) => value.as_mut(),
54            NodeType::ObjectType(ref mut value) => value.as_mut(),
55            NodeType::ReferenceType(ref mut value) => value.as_mut(),
56            NodeType::Variable(ref mut value) => value.as_mut(),
57            NodeType::VariableType(ref mut value) => value.as_mut(),
58            NodeType::View(ref mut value) => value.as_mut(),
59            NodeType::DataType(ref mut value) => value.as_mut(),
60            NodeType::Method(ref mut value) => value.as_mut(),
61        }
62    }
63
64    // Returns the `NodeClass` of this `NodeType`.
65    pub fn node_class(&self) -> NodeClass {
66        match self {
67            NodeType::Object(_) => NodeClass::Object,
68            NodeType::ObjectType(_) => NodeClass::ObjectType,
69            NodeType::ReferenceType(_) => NodeClass::ReferenceType,
70            NodeType::Variable(_) => NodeClass::Variable,
71            NodeType::VariableType(_) => NodeClass::VariableType,
72            NodeType::View(_) => NodeClass::View,
73            NodeType::DataType(_) => NodeClass::DataType,
74            NodeType::Method(_) => NodeClass::Method,
75        }
76    }
77}
78
79/// Implemented within a macro for all Node types. Functions that return a result in an Option
80/// do so because the attribute is optional and not necessarily there.
81pub trait NodeBase {
82    /// Returns the node class - Object, ObjectType, Method, DataType, ReferenceType, Variable, VariableType or View
83    fn node_class(&self) -> NodeClass;
84
85    /// Returns the node's `NodeId`
86    fn node_id(&self) -> NodeId;
87
88    /// Returns the node's browse name
89    fn browse_name(&self) -> QualifiedName;
90
91    /// Returns the node's display name
92    fn display_name(&self) -> LocalizedText;
93
94    /// Sets the node's display name
95    fn set_display_name(&mut self, display_name: LocalizedText);
96
97    fn description(&self) -> Option<LocalizedText>;
98
99    fn set_description(&mut self, description: LocalizedText);
100
101    fn write_mask(&self) -> Option<WriteMask>;
102
103    fn set_write_mask(&mut self, write_mask: WriteMask);
104
105    fn user_write_mask(&self) -> Option<WriteMask>;
106
107    fn set_user_write_mask(&mut self, write_mask: WriteMask);
108}
109
110/// Implemented by each node type's to provide a generic way to set or get attributes, e.g.
111/// from the Attributes service set. Internal callers could call the setter / getter on the node
112/// if they have access to them.
113pub trait Node: NodeBase {
114    /// Finds the attribute and value. The param `max_age` is a hint in milliseconds:
115    ///
116    /// * value 0, server shall attempt to read a new value from the data source
117    /// * value >= i32::max(), sever shall attempt to get a cached value
118    ///
119    /// If there is a getter registered with the node, then the getter will interpret
120    /// `max_age` how it sees fit.
121    fn get_attribute_max_age(
122        &self,
123        timestamps_to_return: TimestampsToReturn,
124        attribute_id: AttributeId,
125        index_range: NumericRange,
126        data_encoding: &QualifiedName,
127        max_age: f64,
128    ) -> Option<DataValue>;
129
130    /// Finds the attribute and value.
131    fn get_attribute(
132        &self,
133        timestamps_to_return: TimestampsToReturn,
134        attribute_id: AttributeId,
135        index_range: NumericRange,
136        data_encoding: &QualifiedName,
137    ) -> Option<DataValue> {
138        self.get_attribute_max_age(
139            timestamps_to_return,
140            attribute_id,
141            index_range,
142            data_encoding,
143            0f64,
144        )
145    }
146
147    /// Sets the attribute with the new value
148    fn set_attribute(
149        &mut self,
150        attribute_id: AttributeId,
151        value: Variant,
152    ) -> Result<(), StatusCode>;
153}