Any elm CLI JSON codegen libraries, like flutter's JsonSerializable/build runner?

Hello. I basically want to mimic this feature that I found on Flutter, which maps dart objects like this:

@JsonSerializable()
class Person {
  Person();

  int? id;
  String? name;

  @JsonKey(name: 'date_of_birth')
  int? dateOfBirth;

  factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
  Map<String, dynamic> toJson() => _$PersonToJson(this);
}

and then when we run in the cli:

flutter pub run build_runner build

the script will create an additional model.g.dart file which contains the de/serialization code like this:

Person _$PersonFromJson(Map<String, dynamic> json) => Person()
  ..id = json['id'] as int?
  ..name = json['name'] as String?
  ..dateOfBirth = json['date_of_birth'] as int?;

Map<String, dynamic> _$PersonToJson(Person instance) => <String, dynamic>{
      'id': instance.id,
      'name': instance.name,
      'date_of_birth': instance.dateOfBirth,
    };

Now I want this for Elm. For example if we have an elm class like this

type alias Customer =
    { -- Base
      uuid : Maybe String
    , createdAt : Maybe Int
    , updatedAt : Maybe Int
    , deletedAt : Maybe Int

    -- Base end
    , name : Maybe String
    , phone : Maybe String
    , address : Maybe String
    }

and then we run something like this:

npm run elm-record-codegen --case camelCase --type pipeline

we get a file containing the automatically mapped en/decoders for the class

customerEncoder : Customer -> Encode.Value
customerEncoder customer =
    Encode.object
        [ -- Base
          ( "uuid", EncodeExtra.maybe Encode.string customer.uuid )
        , ( "createdAt", EncodeExtra.maybe Encode.int customer.createdAt )
        , ( "updatedAt", EncodeExtra.maybe Encode.int customer.updatedAt )
        , ( "deletedAt", EncodeExtra.maybe Encode.int customer.deletedAt )

        -- Base end
        , ( "name", EncodeExtra.maybe Encode.string customer.name )
        , ( "phone", EncodeExtra.maybe Encode.string customer.phone )
        , ( "address", EncodeExtra.maybe Encode.string customer.address )
        ]


customerDecoder : Decode.Decoder Customer
customerDecoder =
    Decode.succeed Customer
        -- Base
        |> Pipeline.required "uuid" (Decode.maybe Decode.string)
        |> Pipeline.required "createdAt" (Decode.maybe Decode.int)
        |> Pipeline.required "updatedAt" (Decode.maybe Decode.int)
        |> Pipeline.required "deletedAt" (Decode.maybe Decode.int)
        -- Base end
        |> Pipeline.required "name" (Decode.maybe Decode.string)
        |> Pipeline.required "phone" (Decode.maybe Decode.string)
        |> Pipeline.required "address" (Decode.maybe Decode.string)

Is there any package which behaves like this? If not, what should I learn to create something like this? I imagine I need an elm source code parser similar to rust’s token parser, detect type aliases in source code, and then finally generate json en/decoders.

It will tremendously help me in creating elm apps which use lots of data with lots of complex data structures, so that i don’t have to type too much boilerplate en/decoders.

I have an unreleased package that sort of does what you have in mind.

It lets you write

type alias Customer =
    { -- Base
      uuid : Maybe String
    , createdAt : Maybe Int
    , updatedAt : Maybe Int
    , deletedAt : Maybe Int

    -- Base end
    , name : Maybe String
    , phone : Maybe String
    , address : Maybe String
    }

customerCodec : Codec e Customer
customerCodec = Debug.todo ""

and then run the package via elm-review to generate the code (you should be able to run it without any set up if you have Node installed and run this npx elm-review --template MartinSStewart/elm-review-todo-it-for-me/preview --fix-all).

Currently it only supports generating codecs for my elm-serialize package. There’s no support for generating ordinary elm/json encoders and decoders but pull requests are welcome.

One difference between this approach and what you might have in mind is that this is “best effort”. There are situations where you’ll have to fill in the blanks. But the hope is to remove most of the burden from writing serialization.

Maybe this is not exactly what you want, but

https://korban.net/elm/json2elm/

it is a wonderful starting point

Hi, I’m using:

It generates JSON encoders/decoders based on Elm types.

1 Like

My homebrew:

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.