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 } 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)); } } } mod tests { use super::*; 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" } } }"#; #[test] fn test_to_json() { // let expected_json = r#"{"key1": "value1","key2": "value2","subkey": {"key3": "value3"}}"#; let json_data = to_json(VDF_DATA); println!("{}", json_data); // 解析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); } #[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); } }