0

我怎么能推这个

["a", "bb", "c", "dd", "e", "ff", "g", "hh"] //type is Vec<String>

对此

fn list_codes() -> BiMap<char, &'static str> 
{
    let letters = BiMap::<char, &str>::new();
    [('a',"cl01"),
     ('b',"cl02"),
     ('c',"cl03"),
     ('d',"cl04")]
        .into_iter()
        .collect()
}

应该是这样的

fn list_codes() -> BiMap<char, &'static str> 
{
     [('a',"cl01"),
     ('b',"cl02"),
     ('c',"cl03"),
     ('d',"cl04"),
     ('a',"bb"),
     ('c',"dd"),
     ('e',"ff"),
     ('g',"hh")]
        .into_iter()
        .collect()
}

其实逻辑很简单。它将从 csv 文件中获取一个列表并导入到 BiMap。导入 bimap 后,程序将使用此 BiMap 对文本进行编码/解码。

附加:

其余代码在这里:

//-------------------------//
#![allow(non_snake_case)]
//-------------------------//
#![allow(dead_code)]
//-------------------------//
#![allow(unused_variables)]
//-------------------------//
#![allow(unused_imports)]
//-------------------------//
// #![allow(inactive_code)]
//-------------------------//

use std::error::Error as stdErr;
use std::io::Error as ioErr;
use std::net::ToSocketAddrs;
use std::process;
use std::env;
use std::fs;
use std::array;
use std::io;
use std::slice::SliceIndex;

use csv::Error as csvErr;
use csv::Reader;
use csv::StringRecord;
use bimap::BiMap;
use directories::ProjectDirs;
use serde::Deserialize;

//#[cfg(doc)] #[doc = include_str!("../Changelog.md")] pub mod _changelog{}
#[derive(Deserialize, Debug)]
struct Config {
    seperator: String,
    list_file_path: String,
}

#[derive(Debug, Deserialize)]
struct Record <'a> {
    letter: char,
    code: &'a str,
}

fn find_and_read_config_file() -> Result<String, ioErr>
{
    if let Some(proj_dirs) = ProjectDirs::from
    (
        "dev",
        "rusty-bois",
        "test-config-parser",
    ) 
    {
        let config_file_name = "settings.toml"; 

        let config_path = proj_dirs.config_dir();

        let config_file = fs::read_to_string(config_path.join(config_file_name),);
        config_file
    }
    else 
    {
        Err(ioErr::new(io::ErrorKind::NotFound, "no"))
    }
}

fn parse_toml() -> String 
{
    let config_file = find_and_read_config_file();
    let config: Config = match config_file
        {
            Ok(file) => toml::from_str(&file).unwrap(),
            Err(_) => Config 
            {
                seperator: "x".to_string(),
                list_file_path: "rdl".to_string(),
            },
        };
    let result = format!("{}\n{}",config.list_file_path, config.seperator);
    return result;
}

fn reformat_parse_toml() -> Vec<String>
{
    let mut vec_values = Vec::new();
    let mut i = 0;
    for values in parse_toml().split("\n")
    {
        vec_values.insert(i,values.to_string());
        i += 1;
    }
    vec_values
}

fn read_and_parse_csv() -> Result<Vec<StringRecord>, csvErr>
{
    let config_vars = reformat_parse_toml();
    let csv_file_path = &config_vars[0];

    let mut rdr = Reader::from_path(csv_file_path)?;
    rdr.records().collect()
}

fn reformat_read_and_parse_csv() -> Vec<String>
{
    let csv_records = read_and_parse_csv();
    let mut csv_records_as_list = Vec::new();
    let mut i = 0;

    for a in csv_records.iter()
    {
        for b in a 
        {
            for c in b 
            {
                csv_records_as_list.insert(i, c.to_string());
                i += 1 
            }
        }
    }
    csv_records_as_list
}

fn input() -> String 
{
    let mut input = String::new();
    match io::stdin().read_line(&mut input) {
        Ok(_) => {
                return input.to_string();
            },
        Err(e) => {
            return e.to_string();
        }
    }
}

fn list_codes() -> BiMap<char, &'static str> 
{
    let letters = BiMap::<char, &str>::new();
    [('a',"cl01"),
    ('b',"cl02"),
    ('c',"cl03"),
    ('d',"cl04")]
        .into_iter()
        .collect()
}

fn coder(flag: &str) -> String 
{
    let letters = list_codes();
    let mut result_raw = String::new();
    let result = String::new();
    let config_vars = reformat_parse_toml();
    let split_char = &config_vars[1];

    if flag == "e"
    {
        println!("Enter the text that you want to encrypt:");
        let ipt = input().trim_end().to_string();
        let ipt_char = ipt.chars();
        for letter in ipt_char
        {
            result_raw = format!("{}{}{}",result_raw,split_char,letters.get_by_left(&letter).unwrap());
        }
        let result = &result_raw[1..];
        return result.to_string();
    }
    else if flag == "d"
    {
        println!("Enter the text that you want to decrypt:");
        let ipt = input().trim_end().to_string();
        let ipt_char = ipt.chars();
        for code in ipt.split(split_char) 
        {
            result_raw = format!("{} {}", result_raw, letters.get_by_right(code).unwrap());
        }
        let decoded = result_raw;
        return decoded;
    }
    else
    {  
        return "Error while decode/encode the input".to_string();
    }
}

fn coder_from_file(flag: &str, path: &str) -> String 
{
    let letters = list_codes();
    let mut result_raw = String::new();
    let result = String::new();
    let contents = fs::read_to_string(path)
    .expect("Something went wrong reading the file");
    let config_vars = reformat_parse_toml();
    let split_char = &config_vars[1];


    if flag == "ef"
    {
        for letter in contents.chars()
        {
            result_raw = format!("{}{}{}",result_raw,split_char,letters.get_by_left(&letter).unwrap());
        }
        let result = &result_raw[1..];
        return result.to_string();
    }
    else if flag == "df" 
    {
        for code in contents.replace("\n", "xpl01").split(split_char) 
        {
            // You might want to have a look at the `String.push_str()` function to avoid creating a new string every time
            result_raw = format!("{}{}", result_raw, letters.get_by_right(code).unwrap());
        }
        let result = result_raw;
        return result;        
    }    
    else
    {  
        return "Error while decode/encode the input".to_string();
    }
}

fn coder_options() -> String
{
    let args: Vec<String> = env::args().collect();
    let mode = &args[1];
    let config_vars = reformat_parse_toml();
    let split_char = &config_vars[1];
   
    let mut m_opt = String::new();

    if mode == "-d"
    {  
        m_opt = coder(&"d");
    }
    else if mode == "-e"
    {
        m_opt = coder(&"e");
    }
    else if mode == "-ef" 
    {
        let filename = &args[2];
        m_opt = coder_from_file(&"ef",&filename);
    }
    else if mode == "-df" 
    {
        let filename = &args[2];
        m_opt = coder_from_file(&"df",&filename);
    }
    else
    {
        println!("You picked wrong flag. Please select a vaild one.")
    }

    return m_opt;

}

fn main () 
{
    let coder_options = coder_options();
    println!("{}", coder_options)
}

这是 Cargo.toml

[package]
name = "Coder"
version = "0.1.0"
edition = "2021"
authors = ["Huso112"]
license= "GPL-3.0"
description = "This program encrypt your datas with special codes."
repository=""

[[bin]]
path = "src/Coder.rs"
name = "Coder"

[dependencies]
bimap = "~0.6.1"
directories = "~4.0.1"
serde = {version="~1.0.133", features=["derive"]}
toml = "~0.5.8"
csv = "~1.1.6"

这是settings.toml文件

seperator = "z"
list_file_path = "/home/hoovy/.config/test-config-parser/lang-table.csv"

这是 lang-table.csv 文件

letter,code
a,bb
c,dd
e,ff
g,hh
4

1 回答 1

0

无聊的方式:

let mut i = 0;
while i < vec_values.len() - 1 {
    let key_str = &vec_values[i];
    let value = &vec_values[i + 1].clone();

    let key = match key_str.chars().nth(0) {
        Some(key) => key,
        None => {
            println!("error: empty key");
            break;
        }
    };

    letters.insert(key, value);
    i += 2;
}

clone()如果您在此之后不需要的版本,则vec_values可以将其拆开:

if vec_values.len() % 2 != 0 {
    println!("error: missing a last value");
    return;
}

while !vec_values.is_empty() {
    // Note: ok to unwrap, because we are sure that vec_values has an even number of values
    let value = vec_values.pop().unwrap();
    let key_str = vec_values.pop().unwrap();

    let key = match key_str.chars().nth(0) {
        Some(key) => key,
        None => {
            println!("error: empty key");
            break;
        }
    };

    letters.insert(key, value);
}

还有一种使用迭代器方法的“智能”方式,但我不会在这里建议它。

于 2022-01-22T20:58:03.330 回答