# abstract struct Enum

- Enum
- Value
- Object

##
Overview

Enum is the base type of all enums.

An enum is a set of integer values, where each value has an associated name. For example:

    enum Color
      Red   # 0
      Green # 1
      Blue  # 2
    end

Values start with the value `0` and are incremented by one, but can be overwritten.

To get the underlying value you invoke value on it:

    Color::Green.value # => 1

Each constant (member) in the enum has the type of the enum:

    typeof(Color::Red) # => Color

###
Flags enum

An enum can be marked with the `@[Flags]` annotation. This changes the default values:

    @[Flags]
    enum IOMode
      Read  # 1
      Write # 2
      Async # 4
    end

Additionally, some methods change their behaviour.

###
Enums from integers

An enum can be created from an integer:

    Color.new(1).to_s # => "Green"

Values that don't correspond to enum's constants are allowed: the value will still be of type Color, but when printed you will get the underlying value:

    Color.new(10).to_s # => "10"

This method is mainly intended to convert integers from C to enums in Crystal.

###
Question methods

An enum automatically defines question methods for each member, using `String#underscore` for the method name.

- In the case of regular enums, this compares by equality (`#==`).
- In the case of flags enums, this invokes `#includes?`.

For example:

    color = Color::Blue
    color.red?  # => false
    color.blue? # => true

    mode = IOMode::Read | IOMode::Async
    mode.read?  # => true
    mode.write? # => false
    mode.async? # => true

This is very convenient in `case` expressions:

    case color
    when .red?
      puts "Got red"
    when .blue?
      puts "Got blue"
    end

###
Changing the Base Type

The type of the underlying enum value is `Int32` by default, but it can be changed to any type in `Int::Primitive`.

    enum Color : UInt8
      Red
      Green
      Blue
    end

    Color::Red.value # : UInt8

##
Included Modules

- Comparable(Enum)

##
Defined in:

enum.cr
json/to_json.cr
yaml/to_yaml.cr

##
Constructors

- .from_value(value : Int) : self

  Returns the enum member that has the given value, or raises if no such member exists.

- .new(ctx : YAML::ParseContext, node : YAML::Nodes::Node)

  Reads a serialized enum member by name from ctx and node.

- .new(value : self)

  Returns value.

- .new(pull : JSON::PullParser)

  Reads a serialized enum member by name from pull.

- .parse(string : String) : self

  Returns the enum member that has the given name, or raises `ArgumentError` if no such member exists.

##
Class Method Summary

- .each(& : self -> )

  Iterates each member of the enum.

- .from_value?(value : Int) : self | Nil

  Returns the enum member that has the given value, or `nil` if no such member exists.

- .names : Array(String)

  Returns all enum members as an `Array(String)`.

- .parse?(string : String) : self | Nil

  Returns the enum member that has the given name, or `nil` if no such member exists.

- .valid?(value : self) : Bool

  Returns `true` if the given value is an enum member, otherwise `false`.

- .values : Array(self)

  Returns all enum members as an `Array(self)`.

##
Macro Summary

- [](*values)

  Convenience macro to create a combined enum (combines given members using `#|` (or) logical operator).

- flags(*values)

  Convenience macro to create a combined enum (combines given members using `#|` (or) logical operator)

##
Instance Method Summary

- #&(other : self) : self

  Returns the enum member that results from applying a logical "and" operation between this enum member's value and other.

- #+(other : Int) : self

  Returns the enum member that results from adding other to this enum member's value.

- #-(other : Int) : self

  Returns the enum member that results from subtracting other to this enum member's value.

- #<=>(other : self)

  Compares this enum member against another, according to their underlying value.

- #==(other : self)

  Returns `true` if this enum member and other have the same underlying value.

- #==(other)

  Returns `false`.

- #^(other : self) : self

  Returns the enum member that results from applying a logical "xor" operation between this enum member's value and other.

- #|(other : self) : self

  Returns the enum member that results from applying a logical "or" operation between this enum member's value and other.

- #~ : self

  Returns the enum member that results from applying a logical "not" operation of this enum member's value.

- #clone
- #each(& : self -> )

  Iterates each values in a Flags Enum.

- #hash(hasher)

  See `Object#hash(hasher)`

- #includes?(other : self) : Bool

  Returns `true` if this enum member's value includes other.

- #inspect(io : IO) : Nil

  Returns an unambiguous `String` representation of this enum member.

- #to_f32 : Float32

  Returns the value of this enum member as a `Float32`

- #to_f32! : Float32

  Returns the value of this enum member as a `Float32`

- #to_f64 : Float64

  Returns the value of this enum member as a `Float64`

- #to_f64! : Float64

  Returns the value of this enum member as a `Float64`

- #to_i : Int32

  Returns the value of this enum member as an `Int32`.

- #to_i128 : Int128

  Returns the value of this enum member as a `Int128`

- #to_i128! : Int128

  Returns the value of this enum member as a `Int128`

- #to_i16 : Int16

  Returns the value of this enum member as a `Int16`

- #to_i16! : Int16

  Returns the value of this enum member as a `Int16`

- #to_i32 : Int32

  Returns the value of this enum member as a `Int32`

- #to_i32! : Int32

  Returns the value of this enum member as a `Int32`

- #to_i64 : Int64

  Returns the value of this enum member as a `Int64`

- #to_i64! : Int64

  Returns the value of this enum member as a `Int64`

- #to_i8 : Int8

  Returns the value of this enum member as a `Int8`

- #to_i8! : Int8

  Returns the value of this enum member as a `Int8`

- #to_json(json : JSON::Builder)

  Serializes this enum member by name.

- #to_s(io : IO) : Nil

  Appends a `String` representation of this enum member to the given io.

- #to_s : String

  Returns a `String` representation of this enum member.

- #to_u128 : UInt128

  Returns the value of this enum member as a `UInt128`

- #to_u128! : UInt128

  Returns the value of this enum member as a `UInt128`

- #to_u16 : UInt16

  Returns the value of this enum member as a `UInt16`

- #to_u16! : UInt16

  Returns the value of this enum member as a `UInt16`

- #to_u32 : UInt32

  Returns the value of this enum member as a `UInt32`

- #to_u32! : UInt32

  Returns the value of this enum member as a `UInt32`

- #to_u64 : UInt64

  Returns the value of this enum member as a `UInt64`

- #to_u64! : UInt64

  Returns the value of this enum member as a `UInt64`

- #to_u8 : UInt8

  Returns the value of this enum member as a `UInt8`

- #to_u8! : UInt8

  Returns the value of this enum member as a `UInt8`

- #to_yaml(yaml : YAML::Nodes::Builder)

  Serializes this enum member by name.

- #value : Int

  Returns the underlying value held by the enum instance.

### Instance methods inherited from module `Comparable(Enum)`

<(other : T) : Bool <, <=(other : T) <=, <=>(other : T) <=>, ==(other : T) ==, >(other : T) : Bool >, >=(other : T) >=, clamp(min, max)
clamp(range : Range) clamp

### Instance methods inherited from struct `Value`

==(other : JSON::Any)
==(other : YAML::Any)
==(other) ==, dup dup

### Instance methods inherited from class `Object`

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other) ===, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash hash, in?(collection : Object) : Bool
in?(*values : Object) : Bool in?, inspect(io : IO) : Nil
inspect : String inspect, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String to_json, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil to_pretty_json, to_s(io : IO) : Nil
to_s : String to_s, to_yaml(io : IO) : Nil
to_yaml : String to_yaml, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

### Class methods inherited from class `Object`

from_json(string_or_io, root : String)
from_json(string_or_io) from_json, from_yaml(string_or_io : String | IO) from_yaml

### Macros inherited from class `Object`

class_getter(*names, &block) class_getter, class_getter!(*names) class_getter!, class_getter?(*names, &block) class_getter?, class_property(*names, &block) class_property, class_property!(*names) class_property!, class_property?(*names, &block) class_property?, class_setter(*names) class_setter, def_clone def_clone, def_equals(*fields) def_equals, def_equals_and_hash(*fields) def_equals_and_hash, def_hash(*fields) def_hash, delegate(*methods, to object) delegate, forward_missing_to(delegate) forward_missing_to, getter(*names, &block) getter, getter!(*names) getter!, getter?(*names, &block) getter?, property(*names, &block) property, property!(*names) property!, property?(*names, &block) property?, setter(*names) setter

##
Constructor Detail

def self.from_value(value : Int) : self #

Returns the enum member that has the given value, or raises if no such member exists.

    Color.from_value(0) # => Color::Red
    Color.from_value(1) # => Color::Green
    Color.from_value(2) # => Color::Blue
    Color.from_value(3) # raises Exception

def self.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node) #

Reads a serialized enum member by name from ctx and node.

See `#to_yaml` for reference.

Raises `YAML::ParseException` if the deserialization fails.

def self.new(value : self) #

Returns value.

def self.new(pull : JSON::PullParser) #

Reads a serialized enum member by name from pull.

See `#to_json` for reference.

Raises `JSON::ParseException` if the deserialization fails.

def self.parse(string : String) : self #

Returns the enum member that has the given name, or raises `ArgumentError` if no such member exists. The comparison is made by using `String#camelcase` and `String#downcase` between string and the enum members names. Dashes (`#-`) in string have the same meaning as an underscore (`_`). A member named "FortyTwo" or "FORTY_TWO" is found with any of these strings: "forty_two", "FortyTwo", "FORTY_TWO", "Forty-Two", "FORTYTWO", "fortytwo".

    Color.parse("Red")    # => Color::Red
    Color.parse("BLUE")   # => Color::Blue
    Color.parse("Yellow") # raises ArgumentError

##
Class Method Detail

def self.each(& : self -> ) #

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

    IOMode.each do |member, value|
      # yield IOMode::Read, 1
      # yield IOMode::Write, 2
      # yield IOMode::Async, 3
    end

def self.from_value?(value : Int) : self | Nil #

Returns the enum member that has the given value, or `nil` if no such member exists.

    Color.from_value?(0) # => Color::Red
    Color.from_value?(1) # => Color::Green
    Color.from_value?(2) # => Color::Blue
    Color.from_value?(3) # => nil

def self.names : Array(String) #

Returns all enum members as an `Array(String)`.

    Color.names # => ["Red", "Green", "Blue"]

def self.parse?(string : String) : self | Nil #

Returns the enum member that has the given name, or `nil` if no such member exists. The comparison is made by using `String#camelcase` and `String#downcase` between string and the enum members names. Dashes (`#-`) in string have the same meaning as an underscore (`_`). A member named "FortyTwo", or "FORTY_TWO" is found with any of these strings: "forty_two", "FortyTwo", "FORTY_TWO", "Forty-Two", "FORTYTWO", "fortytwo".

    Color.parse?("Red")    # => Color::Red
    Color.parse?("BLUE")   # => Color::Blue
    Color.parse?("Yellow") # => nil

If multiple members match the same normalized string, the first one is returned.

def self.valid?(value : self) : Bool #

Returns `true` if the given value is an enum member, otherwise `false`. `false` if not member.

    Color.valid?(Color::Red)   # => true
    Color.valid?(Color.new(4)) # => false

NOTE This is a class method, not an instance method because an instance method `.valid?` is defined by the language when a user defines an enum member named `Valid`.

def self.values : Array(self) #

Returns all enum members as an `Array(self)`.

    Color.values # => [Color::Red, Color::Green, Color::Blue]

##
Macro Detail

macro [](*values) #

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 flags(*values) #

Convenience macro to create a combined enum (combines given members using `#|` (or) logical operator)

    IOMode.flags(Read, Write) # => IOMode[Read, Write]

- `Enum.[]` is a more advanced alternative which also allows int and symbol parameters.

##
Instance Method Detail

def &(other : self) : self #

Returns the enum member that results from applying a logical "and" operation between this enum member's value and other. This is mostly useful with flag enums.

    (IOMode::Read | IOMode::Async) & IOMode::Read # => IOMode::Read

def +(other : Int) : self #

Returns the enum member that results from adding other to this enum member's value.

    Color::Red + 1 # => Color::Green
    Color::Red + 2 # => Color::Blue
    Color::Red + 3 # => Color.new(3)

def -(other : Int) : self #

Returns the enum member that results from subtracting other to this enum member's value.

    Color::Blue - 1 # => Color::Green
    Color::Blue - 2 # => Color::Red
    Color::Blue - 3 # => Color.new(-1)

def <=>(other : self) #

Compares this enum member against another, according to their underlying value.

    Color::Red <=> Color::Blue  # => -1
    Color::Blue <=> Color::Red  # => 1
    Color::Blue <=> Color::Blue # => 0

def ==(other : self) #

Returns `true` if this enum member and other have the same underlying value.

    Color::Red == Color::Red  # => true
    Color::Red == Color::Blue # => false

def ==(other) #
Description copied from struct Value

Returns `false`.

def ^(other : self) : self #

Returns the enum member that results from applying a logical "xor" operation between this enum member's value and other. This is mostly useful with flag enums.

def |(other : self) : self #

Returns the enum member that results from applying a logical "or" operation between this enum member's value and other. This is mostly useful with flag enums.

    (IOMode::Read | IOMode::Async) # => IOMode::Read | IOMode::Async

def ~ : self #

Returns the enum member that results from applying a logical "not" operation of this enum member's value.

def clone #
def each(& : self -> ) #

Iterates each values in a Flags Enum.

    (IOMode::Read | IOMode::Async).each do |member, value|
      # yield IOMode::Read, 1
      # yield IOMode::Async, 3
    end

def hash(hasher) #

See `Object#hash(hasher)`

def includes?(other : self) : Bool #

Returns `true` if this enum member's value includes other. This performs a logical "and" between this enum member's value and other's.

This is mostly useful for flag enums.

For example:

    mode = IOMode::Read | IOMode::Write
    mode.includes?(IOMode::Read)  # => true
    mode.includes?(IOMode::Async) # => false

def inspect(io : IO) : Nil #

Returns an unambiguous `String` representation of this enum member. In the case of a single member value, this is the fully qualified name of the member (equivalent to `#to_s` with the enum name as prefix). In the case of multiple members (for a flags enum), it's a call to `Enum.[]` for recreating the same value.

If the value can't be represented fully by named members, the remaining value is appended.

    Color::Red                     # => Color:Red
    IOMode::None                   # => IOMode::None
    (IOMode::Read | IOMode::Write) # => IOMode[Read, Write]

    Color.new(10) # => Color[10]

def to_f32 : Float32 #

Returns the value of this enum member as a `Float32`

def to_f32! : Float32 #

Returns the value of this enum member as a `Float32`

def to_f64 : Float64 #

Returns the value of this enum member as a `Float64`

def to_f64! : Float64 #

Returns the value of this enum member as a `Float64`

def to_i : Int32 #

Returns the value of this enum member as an `Int32`.

    Color::Blue.to_i                    # => 2
    (IOMode::Read | IOMode::Write).to_i # => 3

    Color.new(10).to_i # => 10

def to_i128 : Int128 #

Returns the value of this enum member as a `Int128`

def to_i128! : Int128 #

Returns the value of this enum member as a `Int128`

def to_i16 : Int16 #

Returns the value of this enum member as a `Int16`

def to_i16! : Int16 #

Returns the value of this enum member as a `Int16`

def to_i32 : Int32 #

Returns the value of this enum member as a `Int32`

def to_i32! : Int32 #

Returns the value of this enum member as a `Int32`

def to_i64 : Int64 #

Returns the value of this enum member as a `Int64`

def to_i64! : Int64 #

Returns the value of this enum member as a `Int64`

def to_i8 : Int8 #

Returns the value of this enum member as a `Int8`

def to_i8! : Int8 #

Returns the value of this enum member as a `Int8`

def to_json(json : JSON::Builder) #

Serializes this enum member by name.

For non-flags enums, the serialization is a JSON string. The value is the member name (see `#to_s`) transformed with `String#underscore`.

    enum Stages
      INITIAL
      SECOND_STAGE
    end

    Stages::INITIAL.to_json      # => %("initial")
    Stages::SECOND_STAGE.to_json # => %("second_stage")

For flags enums, the serialization is a JSON array including every flagged member individually serialized in the same way as a member of a non-flags enum. `None` is serialized as an empty array, `All` as an array containing all members.

    @[Flags]
    enum Sides
      LEFT
      RIGHT
    end

    Sides::LEFT.to_json                  # => %(["left"])
    (Sides::LEFT | Sides::RIGHT).to_json # => %(["left","right"])
    Sides::All.to_json                   # => %(["left","right"])
    Sides::None.to_json                  # => %([])

`ValueConverter.to_json` offers a different serialization strategy based on the member value.

def to_s(io : IO) : Nil #

Appends a `String` representation of this enum member to the given io.

See also: `#to_s`.

def to_s : String #

Returns a `String` representation of this enum member. In the case of regular enums, this is just the name of the member. In the case of flag enums, it's the names joined by vertical bars, or "None", if the value is zero.

If an enum's value doesn't match a member's value, the raw value is returned as a string.

    Color::Red.to_s                     # => "Red"
    IOMode::None.to_s                   # => "None"
    (IOMode::Read | IOMode::Write).to_s # => "Read | Write"

    Color.new(10).to_s # => "10"

def to_u128 : UInt128 #

Returns the value of this enum member as a `UInt128`

def to_u128! : UInt128 #

Returns the value of this enum member as a `UInt128`

def to_u16 : UInt16 #

Returns the value of this enum member as a `UInt16`

def to_u16! : UInt16 #

Returns the value of this enum member as a `UInt16`

def to_u32 : UInt32 #

Returns the value of this enum member as a `UInt32`

def to_u32! : UInt32 #

Returns the value of this enum member as a `UInt32`

def to_u64 : UInt64 #

Returns the value of this enum member as a `UInt64`

def to_u64! : UInt64 #

Returns the value of this enum member as a `UInt64`

def to_u8 : UInt8 #

Returns the value of this enum member as a `UInt8`

def to_u8! : UInt8 #

Returns the value of this enum member as a `UInt8`

def to_yaml(yaml : YAML::Nodes::Builder) #

Serializes this enum member by name.

For non-flags enums, the serialization is a YAML string. The value is the member name (see `#to_s`) transformed with `String#underscore`.

    enum Stages
      INITIAL
      SECOND_STAGE
    end

    Stages::INITIAL.to_yaml      # => %(--- initial\n)
    Stages::SECOND_STAGE.to_yaml # => %(--- second_stage\n)

For flags enums, the serialization is a YAML sequence including every flagged member individually serialized in the same way as a member of a non-flags enum. `None` is serialized as an empty sequence, `All` as a sequence containing all members.

    @[Flags]
    enum Sides
      LEFT
      RIGHT
    end

    Sides::LEFT.to_yaml                  # => %(--- [left]\n)
    (Sides::LEFT | Sides::RIGHT).to_yaml # => %(--- [left, right]\n)
    Sides::All.to_yaml                   # => %(--- [left, right]\n)
    Sides::None.to_yaml                  # => %(--- []\n)

`ValueConverter.to_yaml` offers a different serialization strategy based on the member value.

def value : Int #

Returns the underlying value held by the enum instance.

    enum Color
      Red
      Green
      Blue
    end

    Color::Red.value   # => 0
    Color::Green.value # => 1
    Color::Blue.value  # => 2