pub fn process_d_codes(gerber_data: String) -> String {
let input_lines: Vec<&str> = gerber_data.split('\n').collect();
let mut processed_lines = Vec::with_capacity(input_lines.len());
for current_line in input_lines {
if current_line.contains("%ADD") || current_line.contains("G54D") {
processed_lines.push(current_line.to_string());
continue;
}
let mut updated_line = String::with_capacity(current_line.len() + 10);
let mut last_pos = 0;
let mut search_pos = 0;
while let Some(d_pos) = current_line[search_pos..].find('D') {
let absolute_d_pos = search_pos + d_pos;
let suffix = ¤t_line[absolute_d_pos + 1..];
let num_len = suffix.chars().take_while(|c| c.is_ascii_digit()).count();
if (2..=4).contains(&num_len)
&& suffix.len() > num_len
&& suffix.as_bytes()[num_len] == b'*'
{
let end_of_match = absolute_d_pos + 1 + num_len + 1;
updated_line.push_str(¤t_line[last_pos..absolute_d_pos]);
updated_line.push_str("G54");
updated_line.push_str(¤t_line[absolute_d_pos..end_of_match]);
last_pos = end_of_match;
search_pos = end_of_match;
} else {
search_pos = absolute_d_pos + 1;
}
}
updated_line.push_str(¤t_line[last_pos..]);
processed_lines.push(updated_line);
}
processed_lines.join("\n")
}