Bitstrings to chars - IEx responds true when I ask is_bitstring(d) or is_binary(d)

I am trying Mint.Websocket to connect to a database. I Mint.WebSocket.encode a message, and this returns a mysterious response in the %Mint.WebSocket{} struct. I have no idea how to decipher these guys. The function to_string() does nothing and IEx responds true when I ask is_bitstring(d) or is_binary(d) to the following

<<129, 154, 10, 142, 255, 170, 121, 235, 147, 207, 105, 250, 223, 138, 32, 174,
  153, 216, 101, 227, 223, 203, 99, 252, 143, 197, 120, 250, 197, 155, 45, 181>>
#or
<<129, 155, 70, 67, 37, 92, 37, 49, 64, 61, 50, 38, 5, 61, 47, 49, 85, 51, 52,
   55, 31, 109, 102, 48, 64, 40, 102, 53, 24, 123, 119, 100, 30>>

What format do you expect the response message to have?

Honestly, no idea. Just following this

No, I meant what protocol does you database support? Websocket for transport and what for encoding?

The things you have are not valid binaries, maybe your forgot to decode them, you can confirm that by trying to use IO.puts as it will only print valid strings.

1 Like

String.valid?(d) returns false, and `IO.puts an error

The database accepts strings and I do Mint.WebSocket.encode(websocket, {:text, "create airport:1 set v='1';"})

Yep, and what does it return? Is it a protobuf? Is it a UTF8 JSON? Is it ASCII JSON? Is it coi8 JSON? Is it msgpack?

Don’t know. If I curl the HTTP endpoint, I receive text in the terminal. And I even tried Jason.decode! but I get an error

{:ok, %Mint.WebSocket{extensions: [], fragment: nil, private: %{}, buffer: ""},
 <<129, 155, 64, 58, 161, 241, 35, 72, 196, 144, 52, 95, 129, 144, 41, 72, 209,
   158, 50, 78, 155, 192, 96, 73, 196, 133, 96, 76, 156, 211, 113, 24, 154>>}

So if I decode. i see my query back in fact:

Mint.WebSocket.decode(websocket, data);

{:ok, %Mint.WebSocket{extensions: [], fragment: nil, private: %{}, buffer: ""},
 [text: "create airport:1 set v=\"1\";"]}

In fact, I am sending nothing to the DB…

Any binary is a valid binary. However not every binary holds valid utf-8 text sequences, as confirmed by String.valid?/1 returning false, which means it’s not a valid String.t().

2 Likes

Oh, what? Now that I think about it, it does seem to be strange, because I was always implying that any valid binary is a valid string…

Then it means that is_binary/1 guard has the possibility of accepting possible invalid strings.

Yes. There is no way to check if a binary is a valid String.t() in a guard. Therefore String.valid?/1 is a function.

1 Like

Yeah but that is not a guard, it is strange to me that a guard for checking whether a parameter is string was never added to the language, are there any limitations involved?

It already starts by defining what “is a string”. Elixir chose to use utf8, but erlang used to use latin1 even though nowadays it can also deal with utf8. That’s followed by the fact that parsing a.k.a. validating utf8 can’t be done within the performance constraints of guards.

1 Like

If you get a codepoint that isn’t supported by the formatting then it just lists them all as code points.

For example 129 is a lowercase i with a tilde.

The limitation is that such a guard cannot be written with the functions allowed in guards by the Erlang VM.

Those are not code points, they are byte values of the binary.

Ok thanks for clarifying that for me