msgpack_decimal
https://sr.ht/~nabijaczleweli/msgpack_datetime
https://hexdocs.pm/msgpack_decimal/MsgpackDecimal.html
[Un]pack Elixir :decimal Decimals from/to MessagePack extension fields
msgpack only tries the ext callbacks for tuples
(which is how Erlang structs are implemented) but packs maps (Elixir structs) as maps.
Thus to pack Decimal.new("6.7"), you'd pack it as {MsgpackDecimal, Decimal.new("6.7")},
and you'll get back {MsgpackDecimal, %Decimal{}} in return.
Example, assuming `MsgpackDecimal.extension_type` of 110:
dt = Decimal.new("206.4")
:msgpack.pack({MsgpackDecimal, dt}, ext: MsgpackDecimal)
=== <<214, 110, 255, 205, 8, 16>>
:msgpack.unpack("\\x81\\xC4\\vheading_deg\\xD6n\\xFF\\xCD\\b\\x10", ext: MsgpackDecimal)
=== {:ok, %{"heading_deg" => {MsgpackDecimal, Decimal.new("206.4")}}}
The MsgpackDecimal.StructWrap module contains functions to do this automatically
for terms containing maps and lists:
:msgpack.pack(de |> MsgpackDecimal.StructWrap.wrap(), ext: MsgpackDecimal)
=== <<214, 110, 255, 205, 8, 16>>
{:ok, unpacked} = :msgpack.unpack("\\x81\\xC4\\vheading_deg\\xD6n\\xFF\\xCD\\b\\x10", ext: MsgpackDecimal)
unpacked |> MsgpackDecimal.StructWrap.unwrap()
=== %{"heading_deg" => Decimal.new("206.4")}
The extension type is set from $MsgpackDecimal at build time:
def deps do
[
{:msgpack_decimal, "~> 0.1", system_env: [MsgpackDecimal: "123"]}
]
end
https://hex.pm/packages/msgpack_decimal
A Decimal D can be one of: (https://hexdocs.pm/decimal/Decimal.html)
1. signed NaN
2. signed infinity
3. a number consisting of a sign, coefficient, and exponent such that D = sign * coefficient * 10^exponent
A MsgpackDecimal-encoded Decimal's extension payload can be one of:
1. a one-byte special value
2. the exponent as a raw signed byte, then the signed coefficient as a MessagePacked integer
In case 1, the byte is interpreted as 0bSTTT_TTTT where S is the sign bit and T the type.
Types are 0 for NaN and 1 for infinity. Others are errors.
In case 2, the value of the resulting decimal D is given by D = (signed coefficient) * 10^exponent.
Payloads are distinguished by size: 1 for case 1, ≥2 for case 2. An empty payload is an error.
Release tarballs are signed with nabijaczleweli@nabijaczleweli.xyz
(pull with WKD, but 7D69 474E 8402 8C5C C0C4 4163 BCFD 0B01 8D26 58F1).
аnd stored in git notes as-if via the example program provided at
https://man.sr.ht/git.sr.ht/#signing-tags-tarballs
and are thus available on the refs listing/tag page as .tar.gz.asc.