Roudtrip RON <-> JSON
It seems we can convert from RON to JSON but the inverse has unexpected behavior, calling ron::to_string_pretty() on a serde_json::Value outputs json, not ron.
use anyhow::Result;
pub fn ron_to_json(ron_str: &str) -> Result<String> {
let ron_val = ron::de::from_str::<ron::Value>(ron_str)?;
let json_str = serde_json::to_string_pretty(&ron_val)?;
Ok(json_str)
}
pub fn json_to_ron(json_str: &str) -> Result<String> {
let json_val = serde_json::from_str::<serde_json::Value>(json_str)?;
let ron_str = ron::ser::to_string_pretty(&json_val, Default::default())?;
Ok(ron_str)
}
#[cfg(test)]
mod test {
use anyhow::Result;
use serde::Deserialize;
use serde::Serialize;
use sweet::*;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct MyStruct {
name: String,
age: u32,
}
#[test]
fn ron_to_json() -> Result<()> {
let val = MyStruct {
name: "John".to_string(),
age: 32,
};
let ron_str = ron::ser::to_string_pretty(&val, Default::default())?;
let json = crate::utils::ron_to_json(&ron_str)?;
let ron_str2 = crate::utils::json_to_ron(&json)?;
// this line fails because ron_str2 is outputted in json format
let val2 = ron::de::from_str::<MyStruct>(&ron_str2)?;
expect(val).to_be(val2)?;
println!("{}", ron_str);
println!("{}", json);
println!("{}", ron_str2);
Ok(())
}
}
Yes, that is expected behaviour. RON is a superset of JSON, so all JSON documents are valid RON documents. But RON also supports structs and enums with a Rusty syntax, which is not supported by JSON. In your ron_to_json function, you serialize a ron::Value to JSON, which maps all RON-specific concepts down into JSON in a destructive process, e.g. MyStruct(name: "John", age: 32) becomes {"name": "John", "age": 32}. While RON can still parse this JSON document, it cannot convert it back to the original since a map is not a struct.
TLDR: RON can roundtrip JSON documents (through JSON and RON), but not RON documents through JSON.
Still, a reformulation of this issue is on my long-term TODO list. serde::Value will get some love in a future release to allow all RON documents to roundtrip through it. Perhaps it could then also be given the ability to switch to a more verbose encoding when targeting a non-RON format such that RON -> ron::Value -> JSON -> ron::Value -> RON could roundtrip ... but I'm still not 100% sure that this would work.
Ok that makes sense thanks for the explanation
could you use escape keys like __enum hacks to attempt doing roundtrip?