rust_ethernet_ip/client/
service_layer.rs1use 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}