Python 脚本转成 Rust

技术有限,在Python中写的脚本,在打印结果的时候,真的好慢,读文件也好慢,打包成二进制文件,打开还要等一会才能用,受不了了。一是打包成二进制,不让别人知道怎么搞的,因为是工作中要用的脚本,写给组里用的。二是不让别人看我的烂代码。

于是乎就尝试把他转成Rust,Rust真快,点开就用,打印结果也是 so~ 的一下,爽!!但是写的时候也真的是痛苦,心智负担好大。但是好在最终是能用的,主打能用就行。

以此记录一下。

image.png

Python:

from src.api import redesign_simulation as File
import os
import sys
from collections import OrderedDict


def extract_custom(input_string, start_marker, end_marker):
    # 分割文本以 start_marker 为分隔符
    sections = input_string.split(start_marker)

    # 用于存储所有的内容
    custom_contents = OrderedDict()

    # 遍历分割后的每个部分(除第一个部分外)
    for section in sections[1:]:
        # 找到每个部分中的所有内容
        end_index = section.find(end_marker)
        if end_index != -1:
            content = section[:end_index]
            custom_contents[content] = None

    return list(custom_contents.keys())


def base_path(path):
    if getattr(sys, 'frozen', None):
        basedir = sys._MEIPASS
    else:
        basedir = os.path.dirname(__file__)
    return os.path.join(basedir, path)


def DtcMaskList(sysid):
    cwd = os.getcwd()
    os.chdir(cwd)
    api = File.FileHandler(sysid)
    with open('./xml/Ndtc.xml', 'r', encoding='ANSI') as n:
        content = n.read()
    with open('./xml/CSVFILETEXT.txt', 'r', encoding='ANSI') as c:
        csv = c.read()

    index = api.search_string(f'DD<index=0x{"0" * (8 - len(sysid))}{sysid}>,DD<indexaddr=(.*?)>',
                              content)
    DtcAddr = api.search_string(f'{index}:(.*?)\n{{2}}', content)
    dtccode = extract_custom(DtcAddr, 'DD<code=', '>')
    dtcaddr = extract_custom(DtcAddr, 'DD<dtcaddr=', '>')
    for code, calcid in zip(dtccode, dtcaddr):
        calc = api.search_string(f'{calcid}:.*?DD<DtcMaskCalid=(.*?)>', content)
        calctext = extract_custom(csv, calc + ',	"', '"')
        print(code, calctext, calcid)


if __name__ == '__main__':
    while True:
        try:
            sysid = input('输入sysid:')
            DtcMaskList(f'{sysid}')
            print('\n\n')
        except KeyboardInterrupt:
            print("\n接收到退出信号(Ctrl+C).")
            sys.exit(0)
        except Exception as e:
            continue

Rust:

use std::fs;
use regex::Regex;
use encoding_rs::{GBK};
use std::collections::{HashSet, LinkedList};


enum SearchResult {
    Single(String),
    Multiple((String,String))
}
fn extract_custom(input_string: &str, start_marker: &str, end_marker: &str) -> Vec<String> {
    // 分割文本以 start_marker 为分隔符
    let sections: Vec<&str> = input_string.split(start_marker).collect();

    // 用于存储所有的内容
    let mut custom_contents_set = HashSet::new();
    let mut custom_contents_list = LinkedList::new();

    // 遍历分割后的每个部分(除第一个部分外)
    for section in sections.iter().skip(1) {
        // 找到每个部分中的所有内容
        if let Some(end_index) = section.find(end_marker) {
            let content = &section[..end_index];
            if custom_contents_set.insert(content.to_string()) {
                // 如果该内容之前未被插入,将其插入到链表中
                custom_contents_list.push_back(content.to_string());
            }
        }
    }

    // 将链表转换,保持顺序不变
    custom_contents_list.into_iter().collect()
}

fn search_string(input_string: &str, pattern: &str) -> SearchResult {
    let re = Regex::new(pattern).unwrap();
    if let Some(caps) = re.captures(input_string) {
       if caps.get(2).is_some(){
           let group1 = caps.get(1).unwrap().as_str().to_string();
           let group2 = caps.get(2).unwrap().as_str().to_string();
           return SearchResult::Multiple((group1, group2));
       }else if let Some(match_text) = caps.get(1){
           return SearchResult::Single(match_text.as_str().to_string());
       }
    }
    SearchResult::Single("No match found".to_string())
}




fn main() {
    loop {
        println!("输入sysid:");
        let mut sysid = String::new();
        if let Err(_) = std:🇮🇴:stdin().read_line(&mut sysid) {
            println!("读取输入失败");
            continue;
        }
        let sysid = sysid.trim();

        // 获取当前运行程序的目录
        let current_dir = std::env::current_dir().expect("获取当前目录失败");

        let ndtc_path = current_dir.join("Ndtc.xml");
        let csv_path = current_dir.join("CSVFILETEXT.txt");

        let content_bytes = fs::read(ndtc_path).expect("无法读取Ndtc.xml文件");
        let (content, _, _) = GBK.decode(&content_bytes);

        let csv_bytes = fs::read(csv_path).expect("无法读取CSVFILETEXT.txt文件");
        let (csv, _, _) = GBK.decode(&csv_bytes);



        let len = 8 - sysid.len();
        let zeros = "0".repeat(len);
        let addr = format!("0x{}{}_addr:", zeros, sysid);
        let all_content = extract_custom(&content, &addr, "\r\n\r\n");
        let all_code = &all_content[0];
        let code = extract_custom(all_code, "DD<dtcaddr=", ">");

        for mask in code {
            let pattern = format!("{}:\r\n\tDD<code=(.*?)>,DD<DtcMaskCalid=(.*?)>,DD<TextId=", mask);
            match search_string(&content, &pattern) {
                SearchResult::Single(result) => println!("Result: {}", result),
                SearchResult::Multiple((group1, group2)) => {
                    let csv_pattern = format!("{},\t\"(.*?)\"",&group2);
                    match search_string(&csv,&csv_pattern) {
                        SearchResult::Single(csv_group) => println!("code: {}, calc: {}", group1, csv_group),
                        SearchResult::Multiple(_) => println!("Multiple groups found"),
                    }
                }
            }
        }
    }
}