1use convert::convert_xy_number;
2pub use error::KVError;
3use map::find;
4use regex::split_address;
5use types::DataOProcess;
6
7mod convert;
8mod error;
9mod map;
10mod regex;
11mod types;
12
13pub fn convert_keyence_to_mitsubishi_address(address: &str) -> Result<String, KVError> {
14 let (prefix, address) = split_address(address).ok_or(KVError::PaseError)?;
15 let (instruction, process) = find(prefix).ok_or(KVError::MapNotFound)?;
16
17 match process {
18 DataOProcess::Hex | DataOProcess::Decimal => {
19 let address = address
20 .parse::<u32>()
21 .map_err(|_| KVError::ParseNumberError)?;
22 let (resul1, result2) = (address % 100, (address - address % 100) / 100);
23
24 if resul1 > 16 {
25 return Err(KVError::AddressInvalid);
26 }
27
28 let formatted_result1 = format!("{:X}", resul1);
29 let formatted_result2 = if result2 == 0 && process == DataOProcess::Hex {
30 "".to_string()
31 } else {
32 format!("{:X}", result2)
33 };
34
35 Ok(if process == DataOProcess::Hex {
36 format!("{}{}{}", instruction, formatted_result2, formatted_result1)
37 } else {
38 let decimal =
40 u32::from_str_radix(&format!("{}{}", formatted_result2, formatted_result1), 16)
41 .map_err(|_| KVError::ConvertError)?;
42
43 format!("{}{}", instruction, decimal)
44 })
45 }
46 DataOProcess::DecimalToHex => {
47 let address = address
48 .parse::<u32>()
49 .map_err(|_| KVError::ParseNumberError)?;
50 let formatted_address = format!("{:X}", address);
52 Ok(instruction.to_owned() + &formatted_address)
53 }
54 DataOProcess::XYToHex => Ok(instruction.to_owned() + &convert_xy_number(address)?),
55
56 DataOProcess::None => Ok(instruction.to_owned() + address),
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*; use log;
64
65 #[test]
67 fn test_convert_keyence_to_mitsubishi_address_hex() {
68 let address = "X101";
69 let result = convert_keyence_to_mitsubishi_address(address);
70
71 log::debug!("Result: {:?}", result);
73
74 assert!(result.is_ok()); }
77}