#BitArray value being mutated?

1 messages · Page 1 of 1 (latest)

unreal moon
#

Hey everyone, I have a test:

pub fn decode_fixstr_test() {
  // Fixstr "ok" => tag 0xA2 (length 2), then ASCII for "o", "k"
  <<0xA2, 111, 107>>
  |> tap_inspect
  |> m.msgpack_decode
  |> should.equal(Ok(m.MsgString("ok")))
}

And, inside the msgpack_decode function, I have taps set to print:

pub fn msgpack_decode(bytes: BitArray) -> Result(MsgPack, String) {
  let ins = "Raw bytes:" <> bit_array.inspect(bytes)
  let size = "Bit Size: " <> int.to_string(bit_array.bit_size(bytes))
  io.print(ins)
  io.print(size)
  case bit_array.slice(from: bytes, at: 0, take: 1) {

And inside, we see:

Raw bytes:<<217, 2, 111, 107>>
Bit Size: 32

But, I have the tap, and it prints:

<<162, 111, 107>>

How would the value possibly be mutated like that? I'm not touching it in the tap, and when I run inspect() on it again, we get <<217, 2, 111, 107>>. Any ideas anyone?

cyan star
#

what is tap_inspect?

unreal moon
#

Just a little inline function I can throw in the pipeline

#

I suspect whatever this is is the last holdup I have prior to publishing convert_msgpack

#

But for the life of me I can't figure out what's rolling that first byte up by 1 bit.

#

What's weird is that it's not every test that's doing it, my float32 test completes fine:

pub fn decode_f32_test() {
  // 0xCA = float32, followed by 0x4048F5C3 = 3.140000104904175
  <<0xCA, 0x40, 0x48, 0xF5, 0xC3>>
  |> m.msgpack_decode
  |> should.equal(Ok(m.MsgFloat(3.140000104904175)))
}
cyan star
#

I would guess the <<217, 2, 111, 107>> print is coming from somewhere else

#

also case bit_array.slice(from: bytes, at: 0, take: 1)why dont you use a bit pattern here?

unreal moon
#

I think Phil mentioned something about pattern matching in my use case a while ago, what would that look like there?

#

This is the actual function:

pub fn msgpack_decode(bytes: BitArray) -> Result(MsgPack, String) {
  case bit_array.slice(from: bytes, at: 0, take: 1) {
    Ok(tag_bits) -> {
      let tag = bit_array_to_int_unsigned(tag_bits)
      decode_value(tag, bytes)
    }
    Error(_) -> Error("Bit array too short to contain a tag byte")
  }
}
cyan star
#

a bit pattern would look like this

case bytes {
  <<first, rest:bits>> -> Ok(Nil)
  _ -> Error(Nil)
}
#

you could also match on specific tags like<<0xA2, rest:bits>> -> todo