Skip to main content

rust_ethernet_ip/client/
service_layer.rs

1use super::EipClient;
2use crate::error::{EtherNetIpError, Result};
3use crate::types::{PlcValue, UdtData};
4use crate::udt::UserDefinedType;
5
6impl EipClient {
7    pub async fn write_string_tag(&mut self, tag_name: &str, value: &str) -> Result<()> {
8        self.write_tag(tag_name, PlcValue::String(value.to_string()))
9            .await
10    }
11
12    pub async fn write_udt_member(
13        &mut self,
14        udt_tag_name: &str,
15        member_name: &str,
16        value: PlcValue,
17    ) -> Result<()> {
18        self.write_udt_member_via_full_value(udt_tag_name, member_name, value)
19            .await
20    }
21
22    pub async fn write_udt_array_member(
23        &mut self,
24        udt_array_element_path: &str,
25        member_name: &str,
26        value: PlcValue,
27    ) -> Result<()> {
28        self.write_udt_member_via_full_value(udt_array_element_path, member_name, value)
29            .await
30    }
31
32    async fn write_udt_member_via_full_value(
33        &mut self,
34        udt_tag_name: &str,
35        member_name: &str,
36        value: PlcValue,
37    ) -> Result<()> {
38        let current = self.read_tag(udt_tag_name).await?;
39        let PlcValue::Udt(udt_data) = current else {
40            return Err(EtherNetIpError::DataTypeMismatch {
41                expected: "UDT".to_string(),
42                actual: format!("{current:?}"),
43            });
44        };
45
46        let definition = self.get_udt_definition(udt_tag_name).await?;
47        let mut user_def = UserDefinedType::new(definition.name.clone());
48        for member in &definition.members {
49            user_def.add_member(member.clone());
50        }
51
52        let mut members = udt_data.parse(&user_def)?;
53        if !members.contains_key(member_name) {
54            return Err(EtherNetIpError::TagNotFound(format!(
55                "{udt_tag_name}.{member_name}"
56            )));
57        }
58
59        members.insert(member_name.to_string(), value);
60        let modified = UdtData::from_hash_map(&members, &user_def, udt_data.symbol_id)?;
61        self.write_tag(udt_tag_name, PlcValue::Udt(modified)).await
62    }
63}