defmodule Test do
defmacro bool_to_int(x) do
quote do
case unquote(x) do
true -> 1
false -> 0
end
end
end
defmacro encode_flag(b) do
quote(do: [bool_to_int(unquote(b))::1])
end
def encode(final?, data) do
<<encode_flag(final?), data::bits>>
end
end
But it raises
** (CompileError) iex:35: invalid literal [case(final?) do
true ->
1
false ->
0
end :: 1] in <<>>
(elixir) src/elixir_bitstring.erl:32: :elixir_bitstring.expand/6
(elixir) src/elixir_bitstring.erl:12: :elixir_bitstring.expand/4
iex:34: (module)
Is there a way around this? I’d like to have a helper macro to easily encode flags into bitstrings.
And since <<(if true, do: 1, else: 0)::1>> works fine, I guess it should be possible.
defmodule Test do
defmacro bool_to_int(x) do
quote do
case unquote(x) do
true -> 1
false -> 0
end
end
end
defmacro encode_flag(b) do
quote(do: bool_to_int(unquote(b))::1)
end
def encode(final?, data) do
<<encode_flag(final?), data::bits>>
end
end
Nope, you understood correctly. But as it seems, I have made some wrong assumptions about expansion order here. <<>> seems to not expand before scanning its elements…
but since you can nest binaries the following should do:
defmacro encode_flag(b) do
quote(do: <<bool_to_int(unquote(b))::1>>)
end