<% @enums.each do |enum| -%>
<% ename = underscore(enum[:name]) %>
<%= ename %>.hpp
#pragma once

#include <string_view>

namespace cucumber::messages {

enum class <%= ename %>
{
<%-
  vals = enum[:values].map { |v| enum_constant(v) }
-%>
    <%= vals.join(",\n    ") %>
};

std::string_view
to_string(<%= ename %> v);

std::ostream&
operator<<(std::ostream& os, <%= ename %> v);

}
<%= ename %>.cpp
#include <iostream>
#include <unordered_map>

#include <cucumber/messages/<%= ename %>.hpp>

namespace cucumber::messages {

std::string_view
to_string(<%= ename %> v)
{
    using map_type = std::unordered_map<<%= ename %>, std::string_view>;

    static const map_type m = {
<%- enum[:values].each_with_index do |value, index| -%>
        { <%= ename %>::<%= enum_constant(value) %>, "<%= value %>" }<%= index < enum[:values].length-1 ? ',' : '' %>
<% end -%>
    };

    return m.at(v);
}

std::ostream&
operator<<(std::ostream& os, <%= ename %> v)
{
    os << to_string(v);

    return os;
}

}<%- end -%>
