Hi,
looking into building some MQTT client as an exercise with Roc (at very basic stage still). So far, I am constructing eg. a CONNECT packet by joining various List U8
together (see below an example).
I am wondering if this is "the way to go" or if Roc has some feature that I am missing to work with bit/byte fields.
makeConnect : Str -> List U8
makeConnect = |clientIdStr|
remLength = Num.to_u8(10 + 2 + List.len(Str.to_utf8(clientIdStr)))
fixedHeader = [0x10, remLength]
protocolName = [0x00, 0x04, 0x4d, 0x51, 0x54, 0x54]
protocolLevel = [0x04]
connectFlagsValue = 0b00000010 # Beispiel: Clean Session gesetzt
connectFlags = [connectFlagsValue]
keepAliveValue = 60
keepAliveBytes = [00, keepAliveValue] # Num.toU16(keepAliveValue) |> Num.toBytes(endian: Big)
variableHeader = List.join [protocolName, protocolLevel, connectFlags, keepAliveBytes]
l = List.len(Str.to_utf8(clientIdStr))
clientIdLength = [Num.shift_right_by(Num.to_u8(l), 8), Num.to_u8(Num.bitwise_and(l, 0xFF))]
payload = List.join [clientIdLength, Str.to_utf8(clientIdStr)]
List.join [fixedHeader, variableHeader, payload]
This seems like a reasonable approach. Given the low level nature, I would probably do this kind of thing on the platform side though.
Thanks. Can you elaborate on "the platform side"? Thus far, I am using basic-cli for cli.Tcp.
Can you elaborate on "the platform side"? Thus far, I am using basic-cli for cli.Tcp.
Yes, I was thinking about forking basic-cli and doing the bit twiddling in Rust but now I'm doubting myself :p
Perhaps making an encoder (in pure Roc) may be the best solution.
There's 0b0000_1100
syntax I think. Maybe that helps?
I think this is a good way to do it. As a pure roc library, because then it's cross-platform automatically.
Yeah, roc doesn't really have a better way to do this than what you are currently doing. For generic formats like msgpack, an encoder could be used, but that doesn't help for specific encoding like this.
This is part of the reason I think we still need proper inline bittwiddling symbols
Last updated: Jul 05 2025 at 12:14 UTC