Atdgen wizards: Rust backend?

Any atdgen wizards here with advice for writing a new bakend (Rust) ?

My goal is to be able to write one atdgen def, then to generate types for OCaml, ReScript, Rust, as well as serialization / deserialization types.

2 Likes

I don’t know much about atdgen, but it looks like existing backends “just” take an ATD type description and output a source file in the desired language to express it. The workflow to create a new backend for a new language would presumably be the following:

  • run an existing backend or two on a representative example and understand the output
  • figure out what output you would want in your new language (here Rust), maybe write it by hand and give it a try
  • write a backend that prints this output for you programmatically

Have you tried following this process? Can you say more precisely where you are stuck, where you would need help?

1 Like

If you look in the PR history there was bunch of backends added to atdgen recently, for typescript and python at least. It should give you a good idea of what is required to support another language. I’d encourage you to open an issue or a PR on github if you want more details.

Now, I have not tried this process yet. I could not find any code / tutorial online on adding a backend to atdgen and was hoping, given how similar atdgen syntax is to OCaml, that someone here may have had experience with this.

Thanks, this looks like a good place to start.

1 Like

Hello,

We don’t have a guide for adding new backends yet but it may be a good time to start one. As @Khady said, Python and TypeScript are the latest backends we added and they’re the best examples so far since they avoid the mistakes of their predecessors.

Here are a few more tips:

  • Keep things simple. The original implementation targeting OCaml is atdgen. It is so complicated that we’ve been considering a reimplementation. Much of the complexity is due to handling the conversion from bytes to OCaml without going through an AST representing the JSON data. This was done on purpose to maximize performance but I wouldn’t recommend it. It was fun initially but it’s no fun to extend.
  • You need to pick a Rust JSON parser.
  • You need an intermediate tree type that holds the JSON data. If the parser doesn’t produce one, you should create your own and document it. This allows various fix-ups that are useful in the real world. Support for these fix-ups was complicated to implement in atdgen and we should avoid getting into this situation again.
  • Ask your questions at Issues · ahrefs/atd · GitHub. I don’t know enough about Rust to have a plan for it but other people may have good ideas.
  • Believe in tests! Most tests are end-to-end: given an ATD file, derive Rust code, compile that code, run a simple test executable that reads and writes JSON data. Compare JSON input against JSON output.
  • I find code generation very satisfying. I usually follow @gasche’s advice of writing down sample code by hand to serve as a model when writing the code to generate it.
4 Likes