如何在 Rust 中使用 Vec 扩展 BiMap<String>?



如何推送此

["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

镗孔方式:

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);
}

还有一个";"聪明";方法使用Iterator方法,但我不会在这里建议它。

相关内容

最新更新