Skip to content

Commit

Permalink
Correctly print non-byte aligned bit arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
lpil committed Oct 31, 2023
1 parent aa07fd9 commit 8233587
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/gleam_stdlib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ inspect(Binary) when is_binary(Binary) ->
Segments = [erlang:integer_to_list(X) || <<X>> <= Binary],
["<<", lists:join(", ", Segments), ">>"]
end;
inspect(Bits) when is_bitstring(Bits) ->
inspect_bit_array(Bits);
inspect(List) when is_list(List) ->
case inspect_list(List) of
{proper, Elements} -> ["[", Elements, "]"];
Expand Down Expand Up @@ -457,6 +459,28 @@ inspect_list([First | Rest]) when is_list(Rest) ->
inspect_list([First | ImproperTail]) ->
{improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}.

inspect_bit_array(Bits) ->
Text = inspect_bit_array(Bits, <<"<<">>),
<<Text/binary, ">>">>.

inspect_bit_array(<<>>, Acc) ->
Acc;
inspect_bit_array(<<X, Rest/bitstring>>, Acc) ->
inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X)));
inspect_bit_array(Rest, Acc) ->
Size = bit_size(Rest),
<<X:Size>> = Rest,
X1 = erlang:integer_to_binary(X),
Size1 = erlang:integer_to_binary(Size),
Segment = <<X1/binary, ":size(", Size1/binary, ")">>,
inspect_bit_array(<<>>, append_segment(Acc, Segment)).

append_segment(<<"<<">>, Segment) ->
<<"<<", Segment/binary>>;
append_segment(Acc, Segment) ->
<<Acc/binary, ", ", Segment/binary>>.


inspect_maybe_utf8_string(Binary, Acc) ->
case Binary of
<<>> -> {ok, <<$", Acc/binary, $">>};
Expand Down
7 changes: 7 additions & 0 deletions test/gleam/string_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,13 @@ pub fn inspect_erlang_atom_with_leading_digit_invalid_in_gleam_test() {
|> should.equal("atom.create_from_string(\"1Ok\")")
}

@target(erlang)
pub fn fifteen_bit_int_test() {
<<2, 3:size(7)>>
|> string.inspect
|> should.equal("<<2, 3:size(7)>>")
}

pub fn byte_size_test() {
let assert 0 = string.byte_size("")
let assert 1 = string.byte_size("a")
Expand Down

0 comments on commit 8233587

Please sign in to comment.