How do I convert a binary into a list of structs in Elixir?

Viewed 68

I have a binary as follows: <<123, 249, 222, 67, 253, 128, 131, 231, 101>>

And I'd like to transform it into a list of structs like this:

[%RGB{red: 123, green: 249, blue: 222}, %RGB{red: 67, green: 253, blue: 128}, %RGB{red: 131, green: 231, blue: 101}].

The RGB struct is defined like this:

defmodule RGB do
  defstruct red: 0, green: 0, blue: 0
end

I have tried the following method:

  def to_rgb(data) when is_binary(data) do
    stage = 0 # R:0, G:1, B:2, 3:Complete
    rgb = %RGB{}
    rgblist = []
    for x <- :binary.bin_to_list(data) do
      cond do
        stage == 0 -> rgb = %{rgb | red: x}
        stage == 1 -> rgb = %{rgb | blue: x}
        stage == 2 -> rgb = %{rgb | green: x}
      end
      if stage == 3 do
        rgblist = rgblist ++ [rgb]
        stage = 0
      end
    end
    rgblist
  end

But it is far from elegant and doesn't work (the return value is an empty list).

1 Answers

You can parse the r, g, b values out of the binary 3 at a time using bitstring generators, and place them into the struct:

def to_rgb(data) when is_binary(data) and rem(byte_size(data), 3) == 0 do
  for <<r, g, b <- data>> do
    %RGB{red: r, green: g, blue: b}
  end
end

Output:

[
  %RGB{blue: 222, green: 249, red: 123},
  %RGB{blue: 128, green: 253, red: 67},
  %RGB{blue: 101, green: 231, red: 131}
]
Related