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