ahrefs/atd

Nested defaults for config parsing

Lupus opened this issue · 4 comments

Lupus commented

I'm trying to write an atd specification to parse config. I want to have hierarchical config to group related properties together. To do this I create some record type for one part of configuration, annotate it with defaults, and want to embed that into the larger config record. Nested config has defaults for all fields, but when adding that as a ~ field to larger config - I'm forced to provide default value as well, which would lead to duplication of my default values. Hopefully illustrative example:

type a_config = {
  ~a
    <ocaml default="42">
    : int;
}

type b_config = {
    ~a
      <ocaml default="???">
      : a_config;
}

Is it possible to make atdgen copy my defaults over, or just use the constructor function for nested record types? I can't do that myself as it's referenced from the same module and some other module, so without module name it will fail when referenced from other file, and with module name it will fail when referenced from within the same module.

The following is a bit hacky but should work:

(* config.atd *)

type a_config = {
  ~a
    <ocaml default="42">
    : int;
}

type b_config = {
    ~a
      <ocaml default="create_a_config ()">
      : a_config;
}

And call the following commands:

atdgen -v config.atd
atdgen -j -j-std -open Config_v config.atd

This inserts open Config_v at the beginning of config_j.ml, allowing the function create_a_config to be referenced directly.

Lupus commented

It is quite hacky indeed! Thanks @mjambon I'll try it out! Maybe this pattern is worth supporting with some native feature in the long run?

Perhaps the best way would be to generate a single ml/mli pair of files. I'm thinking of the following module structure for an input file example.atd:

module Example:
├── type bar
├── type foo
├── val create_bar
├── val create_foo
├── module Biniou
├── module JSON
└── module Validate

The create_ functions would move out of the validation module (currently obtained with -v) and would become available to the submodules Biniou, JSON, and Validate. These submodules would be independent of one another and would be generated optionally.

Lupus commented

Single output file would be really awesome - 3 times less custom rules in dune. I see no obvious drawbacks with this approach.