wingyplus
I just did a dirty hack after seeing Zoi on x.com a few hours ago.
Quick Introduction
The zoi_defstruct is a library to help you generate a struct from the Zoi object schema (over Zoi.object). Let’s see a small example below:
defmodule K8S.Deployment do
use ZoiDefstruct
@schema Zoi.object(%{
apiVersion: Zoi.string(),
metadata:
Zoi.object(%{
name: Zoi.string()
}),
spec:
Zoi.object(%{
replicas: Zoi.integer() |> Zoi.optional()
})
})
defstructure(@schema)
end
When you call a defstructure The macro generates a struct with enforced keys and typespec for you automatically. So in the IEx, you can see:
A struct:
iex(4)> K8S.Deployment.__struct__()
%K8S.Deployment{spec: nil, metadata: nil, apiVersion: nil}
A typespec declaration:
iex(1)> t K8S.Deployment
@type t() :: %{
spec: %{optional(:replicas) => integer()},
metadata: %{name: binary()},
apiVersion: binary()
}
ArgumentError if it has no required keys:
iex(5)> %K8S.Deployment{}
** (ArgumentError) the following keys must also be given when building struct K8S.Depl
oyment: [:spec, :metadata, :apiVersion]
(examples 0.1.0) expanding struct: K8S.Deployment.__struct__/1
iex:5: (file)
Since this is a quick hack, it has numerous edge cases that need to be addressed. Please feel free to provide feedback or suggestions. Opening an issue or pull request is very welcome.
I need to give special thanks to Zoi for making this awesome library!
Trending in Announcing
WebAuthnLiveComponent WebAuthnComponents
See this post about renaming the package.
Passwordless authentication for Phoenix LiveView app...
New
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
I released Doggo, a collection of unstyled Phoenix components.
https://github.com/woylie/doggo
Features
Unstyled Phoenix components....
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
Hi everyone,
I’ve been working on this protobuf library for 3 years. We use it in the company I work for, EasyMile, to communicate with ...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
I’ll shortly be launching Text, a nascent text analysis library.
Current functionality
In this early version (not ready for prime time) ...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with.
But I don’t use it anymore.
Serverless was the promis...
New
Hey folks,
I just published a post about Hologram’s funding and where the project goes next - the short version:
Curiosum as Main Spons...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ai
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex











Showing Posts 1 to 9- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
byu
Great. will check it out.
How does it differ from zoi/lib/zoi/struct.ex at main · phcurado/zoi · GitHub ?
phcurado
awesome @wingyplus
You can leverage some of the helpers on the Zoi Struct module as @byu mentioned. I personally decided to not add any macros into the library (unless strictly necessary like infering type specs) but I added these helpers for anyone who wishes to extend it.
Thanks for using
Zoi, awesome to see thiswingyplus
Thanks for the comment
Actually, it’s a wrapper of those three functions to avoid repetition works.
wingyplus
Thanks for the comment.
I just see that
Zoihas a struct helper already (from @byu mentioned). Will refactoring to use those functions instead.nulltree
I’m so happy libraries like
Zoiseem to catch on and inspire extension (infant adoption steps, but still).They complement my way of thinking really well!
wingyplus
Update from the latest main. The
defstructureis now changed todefstructand you can embed the schema intodefstructdirectly.The API also use
Zoi.Structunder the hood. So the enforce keys and struct declaration is now align with the Zoi upstream.wingyplus
Type composition is now working! You can use
t()function to reference another struct.wingyplus
The library is now published on Hex zoi_defstruct | Hex . Feel free to provide feedback, open issues, or pull requests.
charlieaten
Great work @wingyplus, this is some inspiring stuff.
One concern I had though with this approach is that having a
defstruct-like DSL that looks likeKernel.defstructbut behaves differently can be confusing.Your work inspired me to experiment with Sigil, a proof-of-concept DSL for defining nested structs and validating external data using Zoi:
I’m still iterating and may try more compact forms for types like:
This has been a great way to learn macros and DSL design, and aims to complement(and obviously heavily inspired by) Ecto. Whereas Ecto handles data mapping and persistence at the external data/application(and database) layer, validation libraries like zoi and the likes and thus Sigil aim to provide a layer that works great for things like wrapping external api’s into client libraries and doing validation and egornomic casting into elixir constructs.
Thanks again—I hope others find it interesting.