opcua_types/
event_field.rs1use std::collections::HashMap;
4
5use crate::{Array, AttributeId, IntoVariant, NumericRange, QualifiedName, Variant, VariantType};
6
7pub trait EventField {
9 fn get_value(
17 &self,
18 attribute_id: AttributeId,
19 index_range: &NumericRange,
20 remaining_path: &[QualifiedName],
21 ) -> Variant;
22}
23
24impl<T> EventField for T
25where
26 T: IntoVariant + Clone,
27{
28 fn get_value(
29 &self,
30 attribute_id: AttributeId,
31 index_range: &NumericRange,
32 remaining_path: &[QualifiedName],
33 ) -> Variant {
34 if !remaining_path.is_empty()
35 || attribute_id != AttributeId::Value
36 || !matches!(index_range, NumericRange::None)
37 {
38 return Variant::Empty;
39 }
40 let val: Variant = self.clone().into_variant();
41 val.range_of_owned(index_range).unwrap_or(Variant::Empty)
42 }
43}
44
45impl<T> EventField for Option<T>
46where
47 T: EventField,
48{
49 fn get_value(
50 &self,
51 attribute_id: AttributeId,
52 index_range: &NumericRange,
53 remaining_path: &[QualifiedName],
54 ) -> Variant {
55 let Some(val) = self.as_ref() else {
56 return Variant::Empty;
57 };
58 val.get_value(attribute_id, index_range, remaining_path)
59 }
60}
61
62impl<T> EventField for Vec<T>
63where
64 T: EventField + Clone + VariantType,
65{
66 fn get_value(
67 &self,
68 attribute_id: AttributeId,
69 index_range: &NumericRange,
70 remaining_path: &[QualifiedName],
71 ) -> Variant {
72 if !remaining_path.is_empty() {
73 return Variant::Empty;
74 }
75
76 let values: Vec<_> = match index_range {
77 NumericRange::None => self
78 .iter()
79 .map(|v| v.get_value(attribute_id, &NumericRange::None, &[]))
80 .collect(),
81 NumericRange::Index(i) => {
82 return self.get((*i) as usize).cloned().get_value(
83 attribute_id,
84 &NumericRange::None,
85 &[],
86 );
87 }
88 NumericRange::Range(s, e) => {
89 if e <= s {
90 return Variant::Empty;
91 }
92 let Some(r) = self.get(((*s) as usize)..((*e) as usize)) else {
93 return Variant::Empty;
94 };
95 r.iter()
96 .map(|v| v.get_value(attribute_id, &NumericRange::None, &[]))
97 .collect()
98 }
99 NumericRange::MultipleRanges(r) => {
100 let mut values = Vec::new();
101 for range in r {
102 match range {
103 NumericRange::Index(i) => {
104 values.push(self.get((*i) as usize).cloned().get_value(
105 attribute_id,
106 &NumericRange::None,
107 &[],
108 ));
109 }
110 NumericRange::Range(s, e) => {
111 if e <= s {
112 return Variant::Empty;
113 }
114 let Some(r) = self.get(((*s) as usize)..((*e) as usize)) else {
115 continue;
116 };
117 values.extend(
118 r.iter()
119 .map(|v| v.get_value(attribute_id, &NumericRange::None, &[])),
120 )
121 }
122 _ => return Variant::Empty,
123 }
124 }
125 values
126 }
127 };
128
129 let Ok(arr) = Array::new(T::variant_type_id(), values) else {
130 return Variant::Empty;
131 };
132 Variant::Array(Box::new(arr))
133 }
134}
135
136impl EventField for Variant {
137 fn get_value(
138 &self,
139 attribute_id: AttributeId,
140 index_range: &NumericRange,
141 remaining_path: &[QualifiedName],
142 ) -> Variant {
143 if !remaining_path.is_empty() || attribute_id != AttributeId::Value {
144 return Variant::Empty;
145 }
146 self.clone()
147 .range_of_owned(index_range)
148 .unwrap_or(Variant::Empty)
149 }
150}
151
152impl EventField for NumericRange {
153 fn get_value(
154 &self,
155 attribute_id: AttributeId,
156 index_range: &NumericRange,
157 remaining_path: &[QualifiedName],
158 ) -> Variant {
159 if !remaining_path.is_empty() || attribute_id != AttributeId::Value {
160 return Variant::Empty;
161 }
162 let val: Variant = self.to_string().into();
163 val.range_of_owned(index_range).unwrap_or(Variant::Empty)
164 }
165}
166
167#[derive(Debug)]
168pub struct PlaceholderEventField<T> {
170 items: HashMap<QualifiedName, T>,
171}
172
173impl<T> Default for PlaceholderEventField<T> {
174 fn default() -> Self {
175 Self {
176 items: Default::default(),
177 }
178 }
179}
180
181impl<T> PlaceholderEventField<T> {
182 pub fn new() -> Self {
184 Self {
185 items: HashMap::new(),
186 }
187 }
188
189 pub fn get_field(&self, name: &QualifiedName) -> Option<&T> {
191 self.items.get(name)
192 }
193
194 pub fn get_field_mut(&mut self, name: &QualifiedName) -> Option<&mut T> {
196 self.items.get_mut(name)
197 }
198
199 pub fn remove_field(&mut self, name: &QualifiedName) -> Option<T> {
201 self.items.remove(name)
202 }
203
204 pub fn insert_field(&mut self, name: QualifiedName, field: T) -> Option<T> {
206 self.items.insert(name, field)
207 }
208
209 pub fn items_mut(&mut self) -> &mut HashMap<QualifiedName, T> {
211 &mut self.items
212 }
213
214 pub fn items(&self) -> &HashMap<QualifiedName, T> {
216 &self.items
217 }
218}
219
220impl<T: EventField> PlaceholderEventField<T> {
221 pub fn try_get_value(
223 &self,
224 key: &QualifiedName,
225 attribute_id: AttributeId,
226 index_range: &NumericRange,
227 remaining_path: &[QualifiedName],
228 ) -> Option<Variant> {
229 let field = self.get_field(key)?;
230 Some(field.get_value(attribute_id, index_range, remaining_path))
231 }
232}