Skip to content

Commit 617ce6c

Browse files
author
HeroesLament
committed
Commit gmsg v1.0.0
1 parent 6d10357 commit 617ce6c

9 files changed

Lines changed: 1307 additions & 4 deletions

File tree

.github/workflows/test.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: test
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- main
8+
pull_request:
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: erlef/setup-beam@v1
16+
with:
17+
otp-version: "27.1.2"
18+
gleam-version: "1.11.1"
19+
rebar3-version: "3"
20+
# elixir-version: "1"
21+
- run: gleam deps download
22+
- run: gleam test
23+
- run: gleam format --check src test

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.beam
2+
*.ez
3+
/build
4+
erl_crash.dump

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,34 @@
33
[![Package Version](https://img.shields.io/hexpm/v/gmsg)](https://hex.pm/packages/gmsg)
44
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gmsg/)
55

6+
> MessagePack encoding/decoding for Gleam.
7+
8+
## Install
69
```sh
710
gleam add gmsg@1
811
```
12+
13+
## Quick start
914
```gleam
1015
import gmsg
16+
import gleam/io
1117
12-
pub fn main() -> Nil {
13-
// TODO: An example of the project in use
14-
}
18+
let data = gmsg.pack_string("hello")
19+
let Ok(bin) = gmsg.to_bit_array(data)
20+
io.println(bit_array.inspect(bin))
21+
22+
// returns Dynamic
23+
let Ok(dynamic) =
24+
gmsg.parse(bin, using: decode.string)
1525
```
1626

1727
Further documentation can be found at <https://hexdocs.pm/gmsg>.
1828

1929
## Development
2030

2131
```sh
22-
gleam run # Run the project
2332
gleam test # Run the tests
2433
```
34+
35+
## License
36+
Apache-2.0 © HeroesLament

docs/DOGMA.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# DOGMA — Design Principles of `gmsg`
2+
3+
1. **Single pair of public entry-points.**
4+
`encode(msg_pack)` turns a `MsgPack` value into a `BitArray`; `parse(bits, using decoder)` turns a `BitArray` back into a typed value via a `dynamic.Decoder`.
5+
6+
2. **Three-layer architecture.**
7+
*Wire format* ↔︎ **`MsgPack` IR** ↔︎ **`dynamic.Dynamic`** ↔︎ *your domain type*; the middle two layers mirror Gleam’s JSON codec so one decoder can serve all formats.
8+
9+
3. **Deterministic output.**
10+
Integers are big-endian, lengths are canonical, and arrays/maps preserve caller order, guaranteeing byte-stable hashes and signatures.
11+
12+
4. **Offset-aware streaming.**
13+
The parser returns `(value, next_bit)` tuples internally, letting higher-level helpers walk large documents without copying.
14+
15+
5. **Backend agnostic.**
16+
Pure Gleam: works unchanged on Erlang or JavaScript, needs no NIFs, and allocates minimally.

docs/EXAMPLES.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# gmsg examples — direct MsgPack IR
2+
3+
Below are three short Gleam snippets that build `MsgPack` values by hand, pass them to `gmsg.encode/1`, and (optionally) round-trip with `decode_msgpack_from_bit_offset/2`.
4+
All of them avoid the **dynamic** layer so you can see the raw IR helpers in action.
5+
6+
---
7+
8+
## 1 · Single user record (map)
9+
10+
```gleam
11+
import gmsg
12+
import gleam/bit_array.{inspect}
13+
14+
let user =
15+
gmsg.map(
16+
from: [#("id", 42), #("name", "Ada"), #("active", True)],
17+
of: gmsg.pack_string,
18+
and: fn
19+
Int(i) -> gmsg.pack_int(i)
20+
String(s) -> gmsg.pack_string(s)
21+
Bool(b) -> gmsg.pack_bool(b)
22+
_ -> gmsg.pack_nil()
23+
)
24+
25+
let Ok(bin) = gmsg.to_bit_array(user)
26+
inspect(bin) |> io.println
27+
```
28+
29+
## 2 · List of users
30+
```
31+
import gmsg
32+
33+
let users =
34+
gmsg.array(
35+
from: [
36+
gmsg.map(
37+
from: [#("id", 1), #("name", "Ada")],
38+
of: gmsg.pack_string,
39+
and: gmsg.pack_int
40+
),
41+
gmsg.map(
42+
from: [#("id", 2), #("name", "Grace")],
43+
of: gmsg.pack_string,
44+
and: gmsg.pack_int
45+
)
46+
],
47+
of: fn(x) { x } // elements already MsgPack
48+
)
49+
50+
let Ok(payload) = gmsg.to_bit_array(users)
51+
```
52+
53+
## 3 · Round-trip sanity check
54+
```
55+
import gmsg
56+
import gleam/result
57+
58+
let original = gmsg.pack_string("hello, MsgPack!")
59+
let Ok(bits) = gmsg.to_bit_array(original)
60+
61+
case gmsg.decode_msgpack_from_bit_offset(bits, 0) {
62+
Ok(#(value, _)) -> assert value == original
63+
Error(e) -> io.println("decode error: " <> e)
64+
}
65+
```

gleam.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name = "gmsg"
2+
version = "1.0.0"
3+
4+
description = "MessagePack encoding/decoding for Gleam."
5+
licences = ["Apache-2.0"]
6+
repository = { type = "github", user = "HeroesLament", repo = "gmsg" }
7+
links = [{ title = "Website", href = "" }]
8+
9+
[dependencies]
10+
gleam_stdlib = ">= 0.61.0 and < 2.0.0"
11+
12+
[dev-dependencies]
13+
gleeunit = ">= 1.0.0 and < 2.0.0"

manifest.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# This file was generated by Gleam
2+
# You typically do not need to edit this file
3+
4+
packages = [
5+
{ name = "gleam_stdlib", version = "0.61.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3DC407D6EDA98FCE089150C11F3AD892B6F4C3CA77C87A97BAE8D5AB5E41F331" },
6+
{ name = "gleeunit", version = "1.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "63022D81C12C17B7F1A60E029964E830A4CBD846BBC6740004FC1F1031AE0326" },
7+
]
8+
9+
[requirements]
10+
gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" }
11+
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }

0 commit comments

Comments
 (0)