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

Custom JSON serialization with Ion-Jackson possible, for interop with languages that don't have Ion SDK's? #119

Open
GavinRay97 opened this issue Apr 9, 2022 · 3 comments

Comments

@GavinRay97
Copy link
Contributor

GavinRay97 commented Apr 9, 2022

Taking the example of the Calculator AST from the docs, serializing a simple plus(3, 5) expression as JSON:

fun example() {
    val ast = EnhancedCalculatorAst.build {
        binary(plus(), lit(3), lit(5))
    }
    val sexpr = ast.toIonElement()

    val astString = StringBuilder()
    val ionWriter = IonTextWriterBuilder.json().build(astString)

    sexpr.writeTo(ionWriter)
    println("Serialized AST $astString")
}

You get:

Serialized AST ["binary",["plus"],["lit",3],["lit",5]]

For languages that don't have an Ion SDK, the object ["binary",["plus"],["lit",3],["lit",5]] isn't very easily constructed or comprehended.

Is there any way to define or write custom (de)serializers to allow serializing it as something like:

{
  type: "binary",
  operator: "plus",
  left: {
    type: "literal",
    value: 3
  },
  right: {
   type: "literal",
   value: 5
  }
}

Thank you =)

@dlurton
Copy link
Member

dlurton commented May 16, 2022

HI! Thanks for the question and sorry for the delay in a response.

There isn't something built-in currently. Options are:

  • Make a custom freemarker template to generate your (de)serializer., which could work with any format you want. (See the --target=custom command line argument.) The domain model exposed to the freemarker template isn't well documented currently, but here it is. (The domains property becomes the global variable of the same name in the freemarker template.) The freemarker template for the html target target also uses the same domain model--you could by copying and modifying that.
  • Add a feature to use non-default serializers to the generated code. This would involve modifying the Kotlin target's freemarker templates to include this--care would have to be taken to ensure the API of the generated code is backward compatible. This is the harder of the two options.

@dlurton
Copy link
Member

dlurton commented May 18, 2022

I should also add, to get the data classes to work with Jackson, it would be necessary to add a command-line option --enable-jackson (that applies only to the Kotlin target) and then modify the Kotlin template here to emit the appropriate Jackson annotations. I'm not sure if the current maintainers of this package would want this feature, though.

@GavinRay97
Copy link
Contributor Author

GavinRay97 commented May 20, 2022

Ah awesome, looks like it's fairly straightforward to do custom codegen via templates!

Thanks, when I get some free time I'll play around with this and see if I can get it to spit out a wire-friendly JSON representation for sending to other services/languages 👌

I've been meaning to do a blogpost on building a query expression language + IR-translator with PartiQL anyways

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

No branches or pull requests

2 participants