https://github.com/matiascr/etiquette
Etiquette is a library that allows you to write packet specifications in an ergonomic way.
https://github.com/matiascr/etiquette
library protocols
Last synced: 4 months ago
JSON representation
Etiquette is a library that allows you to write packet specifications in an ergonomic way.
- Host: GitHub
- URL: https://github.com/matiascr/etiquette
- Owner: matiascr
- License: mit
- Created: 2025-06-23T21:49:57.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-10-16T17:06:34.000Z (9 months ago)
- Last Synced: 2025-10-21T14:57:12.097Z (9 months ago)
- Topics: library, protocols
- Language: Elixir
- Homepage: https://hexdocs.pm/etiquette
- Size: 61.5 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Etiquette
A new way of creating and following a protocol
## Summary
Following an example Header Packet
Byte 0
Header Fixed
Packet Type
Type-Specific fields
We can turn it into
```elixir
defmodule Example.Spec do
use Etiquette.Spec
packet "Header Packet", id: :header_packet do
field "Header Fixed", 1, fixed: 1, doc: "Whether the packet is a header."
field "Packet Type", 2, doc: "The type of the payload. Can be any 0-3 integer."
field "Type-Specific fields", (..), id: :type_specific_fields, doc: "The packet payload."
end
packet "Hello Packet", of: :header_packet do
field "Packet Type", 2, fixed: 0b00
field "Hello-specific payload", 8, part_of: :type_specific_fields
end
packet "Conversation Packet", of: :header_packet do
field "Packet Type", 2, fixed: 0b01
field "Conversation-specific payload", 8, part_of: :type_specific_fields
end
packet "Bye Packet", of: :header_packet do
field "Packet Type", 2, fixed: 0b11
field "Bye-specific payload", 8, part_of: :type_specific_fields
end
end
```
Such that we now have a specification
```elixir
iex> Example.Spec.is_header_packet?(<<1::1, "A random string inside 30 bytes"::30>>)
true
iex> Example.Spec.is_hello_packet?(<<1::1, 0b00::2, "rest">>)
true
iex> Example.Spec.is_hello_packet?(<<1::1, 0b10::2, "rest">>)
false
iex> Example.Spec.is_bye_packet?(<<1::1, 0b11::2, 0xFF, 0xAA>>)
true
iex> Example.Spec.parse_bye_packet(<<1::1, 0b11::2, 0xFF, 0xAA>>)
{
%{
header_fixed: 1,
packet_type: 3,
bye_specific_payload: 255
},
<<170>>
}
iex> # Notice how only the fields that are not fixed need to be provided
iex> Example.Spec.build_bye_packet(0xFF) |> Example.Spec.parse_bye_packet()
{
%{
header_fixed: 1,
packet_type: 3,
bye_specific_payload: 0xFF
},
""
}
iex> Example.Spec.build_bye_packet(0xFF) |> Example.Spec.is_bye_packet?()
true
```
Not only are the functions available and functional, but the provided
documentation and other arguments are also analyzed to provide in-depth
documentation of each generated function:



# Future work
- [ ] Add support for frames. Add the option to provide a list of frames as part
of a frames field/payload. It should have a similar structure and options
to `Etiquette.Spec.packet/3`.