TsAccess - Getters/Setters generator for TypedStruct

Hello,

recently I started using TypedStruct and also for quite some time I have problem with typos when using structs in elixir, mainly that struct.fiewld_name is not reported during compile time. So I was playing with idea to create plugin for TypedStruct that would generate getter and setter functions for struct. Good thing is, that when I do typo in function name, code don’t compile, another good thing is that it also generate typespecs, so I assume that dialyzer should report when I try to pass wrong type to setter (untested). I used @before_compile and module attributes that TypedStruct is adding to module:

Example:

defmodule Example do
  @before_compile TsAccess
  use TypedStruct

  typedstruct do
    field(:name, :string)
  end
end

iex> Example.name(%Example{}, "John Doe")
%Example{name: "John Doe"}

iex> Example.name(%Example{name: "John Doe"})
"John Doe"

I’m also thinking to do another library (or as another feature to this one) that would generate lenses

What do you think?

3 Likes

Will these throw an error if given a map?

Will these preserve the struct type when setting a value?

If so seems great!

  1. Yes (it did not, but great idea so I added it :D)

  2. Yes

Thank you for feedback

1 Like

Since it is mi first try at doing library for elixir, CR and API critique is welcomed :slight_smile:

Exceptional! Thanks, this is awesome!

Hello again, I just published version 0.5.0 in which typedstruct is not neceseary anymore and also explicit mode was added where you can define getters explicitly:

defmodule Example do
  use TsAccess, explicit: true
  defstruct [
    :accesible,
    :gettable,
    :settable
  ]

  defaccessor :accessible
 
  defgetter :gettable

  defsetter :settable
end

All macros support also setting of attribute type:

defsetter :name, String.t()

In case of nonexplicit mode without typed struct, types for specs can by set using @types module attribute:

defmodule Example do
  use TsAccess

  @types [
    name: String.t()
  ]
  defstruct [
    :name
  ]
end

Hope someone find this usable :slight_smile:
1 Like

0.6.0 I also added lenses generator (base on elixir Access module) generated functions looks like:

get_in(example, [Example.name_lens()])
1 Like

After some sleep I realized that I don’t need postfix _lens, so now lenses are just field functions without arguments a.k.a get_in(example, [Example.name]) function with postfix _lens are generated with deprecation warning. Also any other ideas how further improve it? I have several:

  • in implicit mode add exclude, only to using
  • add prefix, postfix or callback to generate function names
  • explicit deflens, but this is little bit complicated since I don’t know how to check if field exists
  • add alias option to defsetter, defgetter and defaccesor
  • add onli, exclud, onli to defaccessor (in case of explicit lens, to choose what should by generated)

Feedback is welcomed :slight_smile:

1 Like

Ooo I really like how you setup the lenses!

1 Like