Quantcast
Channel: ReScript Forum - Latest posts
Viewing all articles
Browse latest Browse all 2592

Best Approach for Generating ReScript Builder Patterns with Custom Attributes

$
0
0

Hello ReScript community,

I want to perform code generation on simple types by developing a custom attribute. My goal is to generate the corresponding builder pattern for a given type by adding this attribute. I believe there’s a strong use case for this in scenarios like forms, where filling out a type one property at a time is cumbersome, even with make functions.

// src/User.res

@builder
type user = {
  name: string,
  age: int,
}

// Generated output would look like:
// src/generated/UserBuilder.res

type t = {
  name: option<string>,
  age: option<int>,
}

let empty = () => {
  name: None,
  age: None,
}

let withName = (builder: t, name: string) => {
  ...builder,
  name: Some(name),
}

let withAge = (builder: t, age: int) => {
  ...builder,
  age: Some(age),
}

// Build with validation
let build = (builder: t): result<User.user, string> => {
  switch (builder.name, builder.age) {
  | (Some(name), Some(age)) => 
      Ok({
        name,
        age,
      })
  | (None, _) => Error("User name is missing")
  | (_, None) => Error("User age is missing")
  }
}

// Usage example:
let user = UserBuilder.empty()
  ->UserBuilder.withName("John")
  ->UserBuilder.withAge(30)
  ->UserBuilder.build()

Based on this post’s response, I understand that working with PPXs is cautioned against because the AST evolves internally and could cause breakage.

The other option I’m aware of is dumping the AST via npx bsc -dparsetree MyFile.res and working with the generated dump file.

I’ve also considered a pure ReScript/regex solution, but that does not seem idiomatic to me.

What is the best approach for creating an attribute such as the @builder attribute that I hope to develop? Should I use PPX, work with the ReScript AST directly, or is there another recommended approach?


Viewing all articles
Browse latest Browse all 2592

Trending Articles