pub fn convert_byte_array_to_string(data: &[u8]) -> String {
if data.is_empty() {
return String::new();
}
let end = data.iter().position(|&b| b == 0).unwrap_or(data.len());
let valid = &data[..end];
if valid.is_empty() {
return String::new();
}
decode_ethercat_string(valid)
}
pub fn decode_ethercat_string(data: &[u8]) -> String {
if data.is_empty() {
return String::new();
}
if let Ok(s) = std::str::from_utf8(data) {
if has_meaningful_content(s) {
return clean_string(s);
}
}
if data.iter().all(|&b| b < 128) {
let s = std::str::from_utf8(data).unwrap_or("");
if has_meaningful_content(s) {
return clean_string(s);
}
}
let latin1: String = data.iter().map(|&b| b as char).collect();
clean_string(&latin1)
}
fn has_meaningful_content(s: &str) -> bool {
if s.is_empty() {
return false;
}
s.chars().any(|c| !c.is_control() || c == ' ')
}
fn clean_string(s: &str) -> String {
let trimmed_end = s.trim_end_matches(|c: char| c == '\0' || c == '\r' || c == '\n' || c == '\t');
let result = trimmed_end.trim_start_matches(|c: char| c.is_control() && c != ' ');
result.to_string()
}
pub fn convert_fixed_name_to_string(bytes: &[u8; 41]) -> String {
convert_byte_array_to_string(bytes)
}
pub fn bytes_to_hex_display(data: &[u8]) -> String {
data.iter()
.map(|b| format!("{:02X}", b))
.collect::<Vec<_>>()
.join(" ")
}
pub fn ip_to_string(ip: &[u8; 4]) -> String {
format!("{}.{}.{}.{}", ip[0], ip[1], ip[2], ip[3])
}