Skip to content

Commit

Permalink
Add Enum.[] convenience constructor (#12900)
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota authored Jan 25, 2023
1 parent 8fd0e98 commit 9fca36b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
26 changes: 26 additions & 0 deletions spec/std/enum_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,32 @@ describe Enum do
SpecEnum::One.clone.should eq(SpecEnum::One)
end

describe ".[]" do
it "non-flags enum" do
SpecEnum[].should be_nil
SpecEnum[One].should eq SpecEnum::One
SpecEnum[1].should eq SpecEnum::Two
SpecEnum[One, Two].should eq SpecEnum::One | SpecEnum::Two
SpecEnum[One, :two].should eq SpecEnum::One | SpecEnum::Two
SpecEnum[One, 1].should eq SpecEnum::One | SpecEnum::Two
end

it "flags enum" do
SpecEnumFlags.flags.should be_nil
SpecEnumFlags[One].should eq SpecEnumFlags::One
SpecEnumFlags[2].should eq SpecEnumFlags::Two
SpecEnumFlags[One, Two].should eq SpecEnumFlags::One | SpecEnumFlags::Two
SpecEnumFlags[One, :two].should eq SpecEnumFlags::One | SpecEnumFlags::Two
SpecEnumFlags[One, 2].should eq SpecEnumFlags::One | SpecEnumFlags::Two
end

it "private flags enum" do
PrivateFlagsEnum.flags.should be_nil
PrivateFlagsEnum[FOO].should eq PrivateFlagsEnum::FOO
PrivateFlagsEnum[FOO, BAR].should eq PrivateFlagsEnum::FOO | PrivateFlagsEnum::BAR
end
end

describe ".flags" do
it "non-flags enum" do
SpecEnum.flags.should be_nil
Expand Down
24 changes: 24 additions & 0 deletions src/enum.cr
Original file line number Diff line number Diff line change
Expand Up @@ -497,12 +497,36 @@ struct Enum
# ```
# IOMode.flags(Read, Write) # => IOMode::Read | IOMode::Write
# ```
#
# * `Enum.[]` is a more advanced alternative which also allows int and symbol parameters.
macro flags(*values)
{% for value, i in values %}\
{% if i != 0 %} | {% end %}\
{{ @type }}::{{ value }}{% end %}\
end

# Convenience macro to create a combined enum (combines given members using `|` (or) logical operator).
#
# Arguments can be the name of a member, a symbol representing a member name or a numerical value.
#
# ```
# IOMode[Read] # => IOMode[Read]
# IOMode[1] # => IOMode[Read]
# IOMode[Read, Write] # => IOMode[Read, Write]
# IOMode[Read, 64] # => IOMode[Read, 64]
# IOMode[Read, :write, 64] # => IOMode[Read, Write, 64]
# ```
macro [](*values)
{% for value, i in values %}\
{% if i != 0 %} | {% end %}\
{% if value.is_a?(Path) %} \
{{ @type }}::{{ value }} \
{% else %} \
{{ @type }}.new({{value}}) \
{% end %} \
{% end %}\
end

# Iterates each member of the enum.
# It won't iterate the `None` and `All` members of flags enums.
#
Expand Down

0 comments on commit 9fca36b

Please sign in to comment.