rhaiscript / rhai

Rhai - An embedded scripting language for Rust.
https://crates.io/crates/rhai
Apache License 2.0
3.79k stars 177 forks source link

from Map to json #137

Closed jrpascucci closed 4 years ago

jrpascucci commented 4 years ago

parse_json was something that I was looking for: now I'm looking at the other direction: I feel like this might be baked in implicitly somehow, but couldn't guess at it.

So: other than coding it by hand, is there an extant way to deserialize a Map into json?

schungx commented 4 years ago

A Map is simply HashMap<String, Dynamic>. The problem is with Dynamic, which can be a simple dyn Any trait object. It may be your own type that does not support serialization.

All primitive types built into Dynamic implements Debug. Therefore, you can try doing a format("{:?}", map) to serialize the HashMap into something that's very similar to JSON.

Anything that's a trait object will simply print ?.

jrpascucci commented 4 years ago

It may be your own type that does not support serialization

I'm not using my own type, I just used parse_json, manipulate it a bit.

Anything that's a trait object will simply print ?

In my trivial test instance, they all show ?, as all the values are alloc::boxed::Box

Is that not the expected behavior?

json: {"test":"test1","test2":"test2","transmuted":true} Script: map["test3"] = map["test2"];map["test4"] = map["test"]; Output of the above: {"test3": ?, "test2": ?, "jaims.transmuted": ?, "test4": ?, "test": ?}

-- updated -- similarly, in script, using map.to_string() is returning:

{"test": ?, "test2": ?, "test4": ?, "test3": ?, "jaims.transmuted": ?}

schungx commented 4 years ago

Oops, sorry! I know what the problem is.

I have a mod that I haven't land yet. It changes the internal representation of primitive types to an enum instead of a trait object for efficiency. That'd enable the debug print to show up not with ? for primitive types.

You can surf to my branch to check it out.

https://github.com/schungx/rhai/tree/enum-Dynamic

jrpascucci commented 4 years ago

Works great - I noted the () has to get replaced with null, which is fine: I'll definitely use it, but since it's incompatible, maybe it should be wrapped in a feature?

schungx commented 4 years ago

Works great - I noted the () has to get replaced with null, which is fine: I'll definitely use it, but since it's incompatible, maybe it should be wrapped in a feature?

It is never going to be true JSON without a serious serializer.... I can probably put in a serde feature just for that, but that would be too wasteful. It is going to be pretty easy for you to write your own serializer implementation to serialize a Dynamic anyway -- just defer to the appropriate serialization depending on the actual value type, or bail out if it is a trait object.

That way, you can map a () value with null.