Stream: beginners

Topic: How to construct byte fields


view this post on Zulip Jonas Diemer (Mar 24 2025 at 12:32):

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]

view this post on Zulip Anton (Mar 24 2025 at 13:02):

This seems like a reasonable approach. Given the low level nature, I would probably do this kind of thing on the platform side though.

view this post on Zulip Jonas Diemer (Mar 24 2025 at 13:13):

Thanks. Can you elaborate on "the platform side"? Thus far, I am using basic-cli for cli.Tcp.

view this post on Zulip Anton (Mar 24 2025 at 13:34):

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.

view this post on Zulip Luke Boswell (Mar 24 2025 at 20:24):

There's 0b0000_1100 syntax I think. Maybe that helps?

view this post on Zulip Luke Boswell (Mar 24 2025 at 20:25):

I think this is a good way to do it. As a pure roc library, because then it's cross-platform automatically.

view this post on Zulip Brendan Hansknecht (Mar 24 2025 at 22:08):

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.

view this post on Zulip Brendan Hansknecht (Mar 24 2025 at 22:08):

This is part of the reason I think we still need proper inline bittwiddling symbols


Last updated: Jul 05 2025 at 12:14 UTC