@josevalim: I’m trying defguard
now
My current version
Here is my version of guard for rgb(a) check:
defmodule Example do
defguard is_rgb(rgb)
when is_tuple(rgb) and elem(rgb, 0) in 0..255 and elem(rgb, 1) in 0..255 and
elem(rgb, 2) in 0..255 and
(tuple_size(rgb) == 3 or
(tuple_size(rgb) == 4 and elem(rgb, 3) >= 0 and elem(rgb, 3) <= 1))
def sample(rgb) when is_rgb(rgb), do: :ok
# Let's do not remove comment line for now
# def sample(_rgb), do: :error
end
Extra
With call like:
Example.sample(5)
as expected returns error:
** (FunctionClauseError) no function clause matching in Example.sample/1
The following arguments were given to Example.sample/1:
# 1
5
iex:8: Example.sample/1
but … is it possible to describe which guard part fails like in normal function guards?
My question
Is it possible to write it somehow nicer? I would like to separate:
a) rgb check (in 0..255
) of all elements
b) rgba check
I would like to have it looks like:
# Note: this example is only to show what I want to achieve in much more cleaner - not working way
defmodule Example do
# strict 3-element tuple check
defguard is_rgb_strict({red, green, blue}) when red in 0..255 and green in 0..255 and blue in 0..255
# alpha check
defguard is_css_alpha(alpha) when alpha >= 0 and alpha <= 1
# rgba
defguard is_rgba({red, green, blue, alpha}) when is_rgb_strict({red, green, blue}) and is_css_alpha(alpha)
# 3-element tuple guard for is_rgb
defguard is_rgb(rgb = {red, green, blue}) when is_rgb_strict(rgb)
# 4-element tuple guard for is_rgb
defguard is_rgb(rgba) when is_rgba(rgba)
end
Any ideas?
Note: Of course I know that defguard
does not work like I invented it and I don’t ask to change it. I just want to ask for better (if any) version than my original.