Search code examples
macroscrystal-lang

Creating methods with a macro based on the names of an enum


Having a struct with the following enum:

struct Payment
  enum Status
    Open
    Paid
    Failed

    def to_s
      super.downcase
    end
  end

  getter status : String
end

How can I access the enum names in a macro to create methods like open?, paid? and failed??

SOLUTION

Based on @Jonne Haß' proposal, this is what I wanted to achieve:

{% for value in Status.constants %}
  {% downcased = value.stringify.downcase %}
  def {{ downcased.id }}?
    {{ downcased }} == status
  end
{% end %}

Solution

  • With TypeNode#constants:

    struct Payment
      enum Status
        Open
        Paid
        Failed
      end
    
      getter status : Status = Status::Open
    
      {% begin %}
        delegate({{Status.constants.map {|value| value.stringify.downcase + "?" }.join(", ").id}}, to: status)
      {% end %}
    end