2025-03-23 21:55:17 +08:00
|
|
|
|
pub fn to_json(vdf_data: &str) -> String {
|
|
|
|
|
|
let linebreak = match std::env::consts::OS {
|
|
|
|
|
|
"macos" => "\r",
|
|
|
|
|
|
"windows" => "\n",
|
|
|
|
|
|
"linux" => "\n",
|
|
|
|
|
|
_ => "\n",
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
let startpoint = vdf_data.find('{').unwrap_or(0);
|
|
|
|
|
|
let vdf_data = &vdf_data[startpoint..];
|
|
|
|
|
|
|
|
|
|
|
|
let lines: Vec<&str> = vdf_data.split(linebreak).collect();
|
|
|
|
|
|
let mut json_data = String::new();
|
|
|
|
|
|
|
|
|
|
|
|
for line in lines {
|
|
|
|
|
|
let mut line = line.trim_end_matches('\r').trim().to_string();
|
|
|
|
|
|
|
|
|
|
|
|
if line.contains("\"\t\t\"") {
|
|
|
|
|
|
line = line.replace("\"\t\t\"", "\": \"");
|
|
|
|
|
|
line.push(',');
|
|
|
|
|
|
} else if line.contains("\" \"") {
|
|
|
|
|
|
line = line.replace("\" \"", "\": \"");
|
|
|
|
|
|
line.push(',');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
line = line
|
|
|
|
|
|
.replace('{', ": {")
|
|
|
|
|
|
.replace('\t', "")
|
|
|
|
|
|
.replace('}', "},");
|
|
|
|
|
|
|
|
|
|
|
|
json_data.push_str(&line);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
json_data = json_data
|
|
|
|
|
|
.replace(",}", "}")
|
|
|
|
|
|
.trim_start_matches(": ")
|
|
|
|
|
|
.trim_end_matches(',')
|
|
|
|
|
|
.to_string();
|
|
|
|
|
|
|
|
|
|
|
|
json_data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-27 11:30:03 +08:00
|
|
|
|
pub fn to_vdf(json_data: &str) -> String {
|
|
|
|
|
|
let json_value: serde_json::Value = serde_json::from_str(json_data).unwrap();
|
|
|
|
|
|
let mut vdf_data = String::new();
|
|
|
|
|
|
build_vdf(&json_value, &mut vdf_data, 0);
|
|
|
|
|
|
vdf_data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn build_vdf(json_value: &serde_json::Value, vdf_data: &mut String, indent_level: usize) {
|
|
|
|
|
|
match json_value {
|
|
|
|
|
|
serde_json::Value::Object(obj) => {
|
|
|
|
|
|
for (key, value) in obj {
|
|
|
|
|
|
vdf_data.push_str(&"\t".repeat(indent_level));
|
|
|
|
|
|
vdf_data.push_str(&format!("\"{}\"\n", key));
|
|
|
|
|
|
vdf_data.push_str(&"\t".repeat(indent_level));
|
|
|
|
|
|
vdf_data.push_str("{\n");
|
|
|
|
|
|
build_vdf(value, vdf_data, indent_level + 1);
|
|
|
|
|
|
vdf_data.push_str(&"\t".repeat(indent_level));
|
|
|
|
|
|
vdf_data.push_str("}\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
serde_json::Value::String(s) => {
|
|
|
|
|
|
vdf_data.push_str(&"\t".repeat(indent_level));
|
|
|
|
|
|
vdf_data.push_str(&format!("\"{}\"\t\t\"{}\"\n", s, s));
|
|
|
|
|
|
}
|
|
|
|
|
|
_ => {
|
|
|
|
|
|
vdf_data.push_str(&"\t".repeat(indent_level));
|
|
|
|
|
|
vdf_data.push_str(&format!("\"{}\"\t\t\"{}\"\n", json_value, json_value));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-23 21:55:17 +08:00
|
|
|
|
mod tests {
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
2025-03-27 11:30:03 +08:00
|
|
|
|
static VDF_DATA: &str = r#"\"users\"
|
|
|
|
|
|
{
|
|
|
|
|
|
\"76561198315078806\"
|
|
|
|
|
|
{
|
|
|
|
|
|
\"AccountName\" \"_jerry_dota2\"
|
|
|
|
|
|
\"PersonaName\" \"Rop紫(已黑化)\"
|
|
|
|
|
|
\"RememberPassword\" \"1\"
|
|
|
|
|
|
\"WantsOfflineMode\" \"0\"
|
|
|
|
|
|
\"SkipOfflineModeWarning\" \"0\"
|
|
|
|
|
|
\"AllowAutoLogin\" \"1\"
|
|
|
|
|
|
\"MostRecent\" \"1\"
|
|
|
|
|
|
\"Timestamp\" \"1742706884\"
|
|
|
|
|
|
}
|
|
|
|
|
|
\"76561198107125441\"
|
|
|
|
|
|
{
|
|
|
|
|
|
\"AccountName\" \"_im_ai_\"
|
|
|
|
|
|
\"PersonaName\" \"Buongiorno\"
|
|
|
|
|
|
\"RememberPassword\" \"1\"
|
|
|
|
|
|
\"WantsOfflineMode\" \"0\"
|
|
|
|
|
|
\"SkipOfflineModeWarning\" \"0\"
|
|
|
|
|
|
\"AllowAutoLogin\" \"1\"
|
|
|
|
|
|
\"MostRecent\" \"0\"
|
|
|
|
|
|
\"Timestamp\" \"1739093763\"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
|
|
static JSON_DATA: &str = r#"{
|
|
|
|
|
|
"users": {
|
|
|
|
|
|
"76561198315078806": {
|
|
|
|
|
|
"AccountName": "_jerry_dota2",
|
|
|
|
|
|
"PersonaName": "Rop紫(已黑化)",
|
|
|
|
|
|
"RememberPassword": "1",
|
|
|
|
|
|
"WantsOfflineMode": "0",
|
|
|
|
|
|
"SkipOfflineModeWarning": "0",
|
|
|
|
|
|
"AllowAutoLogin": "1",
|
|
|
|
|
|
"MostRecent": "1",
|
|
|
|
|
|
"Timestamp": "1742706884"
|
|
|
|
|
|
},
|
|
|
|
|
|
"76561198107125441": {
|
|
|
|
|
|
"AccountName": "_im_ai_",
|
|
|
|
|
|
"PersonaName": "Buongiorno",
|
|
|
|
|
|
"RememberPassword": "1",
|
|
|
|
|
|
"WantsOfflineMode": "0",
|
|
|
|
|
|
"SkipOfflineModeWarning": "0",
|
|
|
|
|
|
"AllowAutoLogin": "1",
|
|
|
|
|
|
"MostRecent": "0",
|
|
|
|
|
|
"Timestamp": "1739093763"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}"#;
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-03-23 21:55:17 +08:00
|
|
|
|
#[test]
|
|
|
|
|
|
fn test_to_json() {
|
|
|
|
|
|
// let expected_json = r#"{"key1": "value1","key2": "value2","subkey": {"key3": "value3"}}"#;
|
2025-03-27 11:30:03 +08:00
|
|
|
|
let json_data = to_json(VDF_DATA);
|
|
|
|
|
|
println!("{}", json_data);
|
2025-03-23 21:55:17 +08:00
|
|
|
|
|
|
|
|
|
|
// 解析json
|
|
|
|
|
|
let json_value: serde_json::Value = serde_json::from_str(&json_data).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
println!("{}", json_value)
|
|
|
|
|
|
// assert_eq!(to_json(vdf_data), expected_json);
|
|
|
|
|
|
}
|
2025-03-27 11:30:03 +08:00
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
|
fn test_to_vdf() {
|
|
|
|
|
|
// let json_data = r#"{"key1": "value1","key2": "value2","subkey": {"key3": "value3"}}"#;
|
|
|
|
|
|
let vdf_data = to_vdf(JSON_DATA);
|
|
|
|
|
|
|
|
|
|
|
|
println!("{}", vdf_data);
|
|
|
|
|
|
}
|
2025-03-23 21:55:17 +08:00
|
|
|
|
}
|