gluon
gluon copied to clipboard
gluon marshalling complex foreign types
I’m trying to get marshalling a complex foreign type to work on stable (0.8.1).
I’d like to wrap a passed in immutable json::JsonValue and a mutable clone, pass those to gluon, run scripts on it to manipulate the data, then receive the mutated one back. Is there any reason this might not work on 0.8.1? I’m struggling a bit and my life would be easier if rust’s orphan rules were less strict. Q
Details: Taking a cue from the GluonUser<T> example, I’m using a new struct JsonData {inner: JsonValue}, and struggling to get it to work.
Right now, I can’t seem to get the VmType trait on the JsonValue – does this technique only work for something that has a built-in generic?
impl VmType for JsonData where JsonValue: 'static + VmType, {
trait bound json::JsonValue: gluon_vm::api::VmType
is not satisfied
impl VmType for JsonData
| ^^^^^^ the trait gluon_vm::api::VmType
is not implemented for json::JsonValue
Thanks.
Since you can't use derive
for a foreign type, you need to provide a fitting gluon type definition yourself. There are multiple ways you can do it:
- Constructing the type by hand, using the Type enum (not really documented at the moment)
- Defining the type in a gluon file, and loading it before your type is used. In that case you can use
the VmType-derive and specify the gluon type with a
#[gluon(vm_type = "your.qualified.type.name")]
attribute - Similar to the method above, but using [gluon_vm::api::typ::make_source] to generate the gluon type, by using
serde
(needs theserialization
feature)
You can also take a look at the tests for the codegen
crate, there are quite few simple examples in there.
If this doesn't help, maybe you can post some of the relevant code? :)
This seems to be about https://docs.rs/json/0.11.13/json/enum.JsonValue.html ? If that is the case then it is correct that you can't use that directly since it is a foreign type and so you won't be able to implement a trait on it.
You can add a wrapper type like you seem to have but you can't add the where JsonValue: 'static + VmType,
bound since it is impossible to implement VmType
for the remote JsonValue
type.
However, if I were to guess a little at what you want in the end I would actually recommend you depend on the git master for now as there are json support add if you enable the serialization
feature which provides serialization and deserialization as well as Value
type similar to JsonValue
. Documentation is not quite up to date but the source is at https://github.com/gluon-lang/gluon/tree/master/std/json
Unless things go horribly wrong I hope to get 0.9 out during this weekend.
I'm removing the wheres and having other problems with make_type, but maybe this is going to be more of a documentation problem.
@Laegluin I have to say I don't yet know enough to understand your response - but I thank you for it. :)
@Marwes Yes. Okay, will try that. I feel like you're doing more work than I would have thought one would need to do, but maybe json is fundamentally special.
I started looking at how std::io and the like are done, and I don't understand them either, so what do I know. :).
Thank you for your efforts.
Small update wrt master:
the #[repr(transparent)]
attribute is experimental (see issue #43036)
My colleagues are against relying on stuff that needs nightly.
Thanks.
Yes. Okay, will try that. I feel like you're doing more work than I would have thought one would need to do, but maybe json is fundamentally special.
It isn't special in any way, if you had https://docs.rs/json/0.11.13/json/enum.JsonValue.html defined in your own crate then you could easily implement VmType
, Pushable
and Getable
for it (even derive it automatically, as long as all the internal values also get an implementation of the traits).
The issue is only that it is awkward to work with remote types (even serde has issues with this, the remote attribute it uses to workaround this is something I might add at some point https://serde.rs/container-attrs.html#serderemote--).
It is things I 100% want to make easier, but it is still a lot of work to get all the way there.
Another that that would work if you dont want to use master is to define an equivalent to https://docs.rs/json/0.11.13/json/enum.JsonValue.html in your own crate and then add a pair of conversion functions to convert between your JsonValue and the one in the json crate. Then you would only need to convert between these types in the Rust gluon layer but could otherwise derive the necessary traits.