p-kraszewski

p-kraszewski

Macro to generate record and matching @type

I’m looking for some pointers on how to inject a fully customized @type and defrecord definitions from macro.

I’m creating a <<binary>>record() serializer/deserializer generating code based on a textual description of data structure, not far from the idea of ProtoBuf (but with a much simpler binary representation). For each form I’d like to generate a record, a matching typedef and serialize(record) / deserialize(binary) functions.

Function generation part I have mostly sorted out, just type/record generation is missing. I figured out how to manually write the necessary AST, I just want to know if there’s some quote/unquote magic to make that the elegant way, as is suitable for the elegant language Elixir is.

My plan is to transform this:

protocol = [
sata_id_rep: [
      cmd: @cmd_sata_id,
      fields: [
        {:channel, :int, 8, port()},
        {:data, :bin, 512, sector()},
        {:ata_status, :bin, 32, ata_status()}
      ]
    ]
 ]

into this:

Record.defrecord(:sata_id_rep, channel: nil, data: nil, ata_status: nil)

@type sata_id_rep :: record(:sata_id_rep, channel: port(), data: sector(), ata_status: ata_status())

def serialize(sata_id_rep(channel: channel, data: data, ata_status: ata_status)) do
    <<@sata_id_rep,channel::8,data::binary-size(512),ata_status::binary-size(32)>>
end

def deserialize(<<@sata_id_rep,channel::8,data::binary-size(512),ata_status::binary-size(32)>>) do
    sata_id_rep(channel: channel, data: data, ata_status: ata_status)
end

For example: how to express inquote that in @type the first occurrence of sata_id_rep is without colon and the second one with one.

P.S. Of course I did read Metaprogramming Elixir. Didn’t help in my case. I’ve also inspected the source code of typed-struct which didn’t help either (they work with Structs and @type has a fixed name t).

Thanks in advance,

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
nobody
How to bind a phoenix app to a specific ip address? could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; somethi...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: The documentation above suggests that while ...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call t...
New

Other popular topics Top

Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30877 112
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

We're in Beta

About us Mission Statement