async-opcua 0.18.0

OPC UA client and server API
Documentation
mod node_manager;
mod tester;

pub const CLIENT_USERPASS_ID: &str = "sample1";
pub const CLIENT_X509_ID: &str = "x509";

pub use node_manager::*;
use opcua::types::{AttributeId, DataValue, NodeId, ReadValueId, Variant};
use opcua_client::OnSubscriptionNotification;
pub use tester::*;
use tokio::sync::mpsc::UnboundedReceiver;

#[allow(unused)]
pub fn read_value_id(attribute: AttributeId, id: impl Into<NodeId>) -> ReadValueId {
    let node_id = id.into();
    ReadValueId {
        node_id,
        attribute_id: attribute as u32,
        ..Default::default()
    }
}

#[allow(unused)]
pub fn read_value_ids(attributes: &[AttributeId], id: impl Into<NodeId>) -> Vec<ReadValueId> {
    let node_id = id.into();
    attributes
        .iter()
        .map(|a| read_value_id(*a, &node_id))
        .collect()
}

#[allow(unused)]
pub fn array_value(v: &DataValue) -> &Vec<Variant> {
    let v = match v.value.as_ref().unwrap() {
        Variant::Array(a) => a,
        _ => panic!("Expected array"),
    };
    &v.values
}

#[derive(Clone)]
pub struct ChannelNotifications {
    data_values: tokio::sync::mpsc::UnboundedSender<(ReadValueId, DataValue)>,
    events: tokio::sync::mpsc::UnboundedSender<(ReadValueId, Option<Vec<Variant>>)>,
}

impl ChannelNotifications {
    #[allow(clippy::type_complexity)]
    pub fn new() -> (
        Self,
        UnboundedReceiver<(ReadValueId, DataValue)>,
        UnboundedReceiver<(ReadValueId, Option<Vec<Variant>>)>,
    ) {
        let (data_values, data_recv) = tokio::sync::mpsc::unbounded_channel();
        let (events, events_recv) = tokio::sync::mpsc::unbounded_channel();
        (
            Self {
                data_values,
                events,
            },
            data_recv,
            events_recv,
        )
    }
}

impl OnSubscriptionNotification for ChannelNotifications {
    fn on_data_value(&mut self, notification: DataValue, item: &opcua::client::MonitoredItem) {
        let _ = self
            .data_values
            .send((item.item_to_monitor().clone(), notification));
    }

    fn on_event(
        &mut self,
        event_fields: Option<Vec<Variant>>,
        item: &opcua::client::MonitoredItem,
    ) {
        let _ = self
            .events
            .send((item.item_to_monitor().clone(), event_fields));
    }
}