diff --git a/opcua-client/src/session/mod.rs b/opcua-client/src/session/mod.rs index 66a82a45..f3c461a1 100644 --- a/opcua-client/src/session/mod.rs +++ b/opcua-client/src/session/mod.rs @@ -108,8 +108,9 @@ pub(crate) use session_trace; use opcua_core::ResponseMessage; use opcua_types::{ - ApplicationDescription, ContextOwned, DecodingOptions, EndpointDescription, IntegerId, - NamespaceMap, NodeId, RequestHeader, ResponseHeader, StatusCode, TypeLoader, UAString, + ApplicationDescription, ContextOwned, DecodingOptions, EndpointDescription, Error, IntegerId, + NamespaceMap, NodeId, ReadValueId, RequestHeader, ResponseHeader, StatusCode, + TimestampsToReturn, TypeLoader, UAString, VariableId, Variant, }; use crate::browser::Browser; @@ -430,4 +431,59 @@ impl Session { )), ) } + + /// + /// Return namespace array from server + pub async fn read_namespace_array(&self) -> Result, Error> { + let nodeid: NodeId = VariableId::Server_NamespaceArray.into(); + let result = self + .read( + &[ReadValueId::from(nodeid)], + TimestampsToReturn::Neither, + 0.0, + ) + .await + .map_err(|status_code| { + Error::new(status_code, "Reading Server namespace array failed") + })?; + if let Some(Variant::Array(array)) = &result[0].value { + let arr = array + .values + .iter() + .map(|v| { + //TODO iterator can handle result itself!!! + if let Variant::String(s) = v { + s.value().clone().unwrap_or(String::new()) + } else { + String::new() + } + }) + .collect(); + Ok(arr) + } else { + Err(Error::new( + StatusCode::BadNoValue, + format!( + "Server namespace array is None. The server has an issue {:?}", + result + ), + )) + } + } + + /// + /// read namespace array from server and look for supplied namespace url + pub async fn get_namespace_index(&self, url: &str) -> Result { + let array = self.read_namespace_array().await?; + let idx = array.iter().position(|s| s == url).ok_or_else(|| { + Error::new( + StatusCode::BadNoMatch, + format!( + "Url {} not found in namespace array. Namspace array is {:?}", + url, &array + ), + ) + })?; + Ok(idx.try_into().unwrap()) + } }