Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RON support in other languages #306

Open
chriskilding opened this issue Jun 3, 2021 · 11 comments
Open

RON support in other languages #306

chriskilding opened this issue Jun 3, 2021 · 11 comments
Labels

Comments

@chriskilding
Copy link

RON solves a number of pain points with JSON (e.g. it actually supports enums, actually supports types), and unlike most better-than-JSON attempts it's also managed to get some traction - at least within the Rust community.

As such RON is interesting to those of us who are working outside of Rust, who are working on projects where we find that JSON falls a little short of our needs.

Are there any plans for RON support in other languages? If so, what might that look like?

@kvark kvark added the question label Jun 4, 2021
@kvark
Copy link
Collaborator

kvark commented Jun 4, 2021

Good question! I develop everything in Rust these days, so personally I'll unlikely be able to contribute to bindings to other languages. Besides, it's unclear to me how these langs will deal with the strong enum semantics of RON. If there is such an effort, I'd be happy to endorse it :)
Maybe other folks from RON users/community can chime in and help.

@chriskilding
Copy link
Author

As a 'starter for ten' I'm toying with a prototype RON backend for Jackson:

https://github.com/chriskilding/jackson-dataformat-ron

The idea would be to allow users in the JVM world to read or write RON using the Jackson API they already know (ObjectMapper etc).

I don't yet know if Jackson can support everything RON would need as its APIs currently stand, but it's worth an investigation.

@chriskilding
Copy link
Author

Some updates from building that prototype:

In the low level parser/generator APIs, all of RON can be supported.

In the high level ObjectMapper API, all RON concepts with Java equivalents can be supported. That means the only major RON concepts you can't use are:

  • tuples (Java doesn't have them natively)
  • enums with child fields (Java only has simple enums)

There's still some questions outstanding about things like field ordering, which I didn't address in the prototype, but if field ordering is specified in a language-independent way within the RON specification I think it can be dealt with.

To speed up development of the parser side I wrote an ANTLR grammar for RON which can be seen here: https://github.com/chriskilding/jackson-dataformat-ron/blob/main/src/main/antlr4/com/fasterxml/jackson/dataformat/ron/antlr4/RON.g4. ANTLR isn't necessary to build a parser and other options are out there, but the main takeaway is that if the RON specification had a full grammar which could be used directly by parser generators, it would be helpful to ensure correctness.

Overall, it seems that RON would provide value to Java developers in cases where their data model exceeds the limits of JSON's grammar, such as encoding a list of heterogenous types. And if it can provide value in Java it can probably provide value in other languages too.

@chriskilding
Copy link
Author

chriskilding commented Jul 20, 2021

There are possibilities to allow support for the remaining RON concepts in the ObjectMapper, such as providing @RONFormat annotations which would let the user tell Jackson how to de/serialize enums with child fields or tuples.

Example...

@RONFormat(shape = Shape.Enum)
class Dog {
    int barks;
}

versus

// struct is the default shape for POJOs, no annotation is technically necessary
@RONFormat(shape = Shape.Struct)
class Dog {
  int barks;
}

They're slightly more fragile, in that they would require some runtime checks to ensure that a RON enum Dog(1) can only be deserialised to the class Dog if it has a Shape.Enum annotation. But they're possible if required.

@chriskilding
Copy link
Author

chriskilding commented Jul 20, 2021

I didn't address Optionals in the prototype, although they can be used in the low-level parser and generator 'for free' since Some(...) is just another case of an enum.

In JSON there is an expectation that if an optional field "b" is absent you omit it in the JSON, if it's present it is simply included as-is within the JSON:

{
  "a": "foo"
}
{
  "a": "foo",
  "b": "bar"
}

In RON we'd expect the equivalent to be:

(a: "foo")
(
  a: "foo",
  b: "bar",
)

But currently the reference RON parser does not allow the second form. If present an optional value must be wrapped in Some:

(
  a: "foo",
  b: Some("bar"),
)

This seems... awkward.

@FeldrinH
Copy link

There is this extension: https://github.com/ron-rs/ron/blob/master/docs/extensions.md#implicit_some.

@chriskilding
Copy link
Author

Awesome :) thanks for sharing that. It seems like 'explicit Some' is not a hard constraint of the RON format, I'll go add support for 'implicit Some' to the Jackson RON backend.

@sdfgeoff
Copy link

A prototype python exporter is available here: https://github.com/sdfgeoff/blender_bevy_toolkit/blob/master/blender_bevy_toolkit/rust_types/ron.py

It is intentionally very specific. You have to tell it "this is a ron struct, it contains a ron float" rather than giving it a python dict and letting it attempt to figure it out.

@JakkuSakura
Copy link

I'd prefer a ron2json cli tool. So that all other languages can use ron easily(with performance cost but not bottleneck)

@chriskilding
Copy link
Author

A CLI converter tool could be a good idea, however it's an 'and' rather than an 'or' proposition. There is still very much a need for languages to have their own RON de/serializer libraries (so that they can work with RON at reasonable speed, or specify their own field mappings/transformations, and also because shelling out to an external process comes with security/portability issues).

@juliancoffee
Copy link

juliancoffee commented Jan 9, 2024

Speaking of ron2json cli, not every Ron is a valid Json (which was a surprise to me). I tried using serde_json for this, but as it says in its to_string docs, it will fail if it's a map with non-string keys, which is ok for Ron. Maybe there is some other widely supported format which allows that?

Ok, I tried serde_yaml, which allows for non-string keys, but it seems to completely erase enums.
UPD: Oh wait, it's ron's Value doesn't have enums, hmm.

#122

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants