Open Lupus opened 1 year ago
I don't have time for this right now, but I'd certainly be interested in a PR.
There could be a -ocaml_deriving_ppx
option that can be repeated, like so:
$ ocaml-protoc foo.pb -ocaml_deriving_ppx "show {with_path=false}" -ocaml_deriving_ppx eq
and it's collect all the deriving arguments into one [@@deriving show {with_path=false}, eq]
?
So far we have a workaround in our binary, that's using the compilerlib. Once it breaks, maybe we'll invest into a better solution 😁
I'm trying to build a flow with some validation of protobuf types for my Twirp generator (proprietary, uses custom binary to manipulate the
compilerlib
library ofocaml-protoc
). The most optimal way that I found is to transform some per-field options from protobuf spec intoocaml_type_ppx
, that is further processed byocaml-protoc
and resulting annotation gets emitted along with generated OCaml types.compilerlib
provides me with grouped protos, that I traverse to collect per-field validation rules and emit singlederiving
annotation with all the rules passed as the arguments. But when I tried to implement the actual ppx to generate the validation code - I ran into an issue with recursive types. Only one type out of recursive group needs to have thederiving
annotation, otherwise ppxlib calls the deriver multiple times for a whole group or recursive types. See this discuss thread for more context. The proposed solution is to have only onederiving
annotation per group of recursive types and encode rest of validation metadata in custom annotations to each type. This works well with ppxlib, but requires an ugly hack - I'm passing several ppx annotations viaocaml_type_ppx
concatenating them with][@@
in an SQL injection style... I doubt that's the designed way to add multiple ppx to single type, although it works right now. Wanted to discuss if this is good enough and will likely work in future versions, or some separate API might be implemented to allow multiple ppx annotations to be specified for resulting OCaml type in a clean way.Why ppx for validation in first place? I tried to find a way to implement custom codegen on top of
compilerlib
alone, but that seems to be quite complicated. One of the goals is to mark certain fields as required, so that there are nooption
wrappings in the resulting types. So for every message type I want to generate a type that is the same or a bit different with some functions to go from one to another. And code for generating types is large and depends oncompilerlib
internals that are not feasible to be exported as some public API. So I decided to pass some annotations down to OCaml types instead and handle them via ppx for the boilerplate codegen. This model gives somewhat clean separation of concerns.