Enum to JSON

Is it possible to serialize Enum to JSON based on String representation of the value in the JSON object in case the JSON String name differ from the Enum name?
Is it possible with JSON::Field, or I have to use a custom converter?

enum Layout
  # value in JSON: `splith`
  Horizontal
  # value in JSON: `splitv`
  Vertical
  # JSON: `stacked`
  Stacked
  # JSON: `tabbed`
  Tabbed
end

Enum values are serialized to their numerical representation. But there’s a recent PR to change that to serializes by name: Serialize Enum to underscored String by caspiano · Pull Request #9905 · crystal-lang/crystal · GitHub

So currently, this is not possible directly - and the mentioned PR does not add an option to configure a name mapping either (that could be added later, though).

It should be rather easy to implement specific for your use case:

require "json"
 
enum Layout
  # value in JSON: `splith`
  Horizontal
  # value in JSON: `splitv`
  Vertical
  # JSON: `stacked`
  Stacked
  # JSON: `tabbed`
  Tabbed
  
  def json_name
    case self
    in Horizontal then "splith"
    in Vertical   then "splitv"
    in Stacked    then "stacked"
    in Tabbed     then "tabbed"
    end
  end
            
  def to_json(builder : JSON::Builder)
    builder.scalar json_name
  end
end
       
Layout.values.to_json # => "[\"splith\",\"splitv\",\"stacked\",\"tabbed\"]"

https://carc.in/#/r/aar4

3 Likes

Thank you. How can I mark it as solved?

You’re welcome.

There’s no action for marking a forum thread as solved. Could perhaps add a [SOLVED] tag to the title, but that’s not common here. Just let it rest and vanish in the archives ;)

Btw. a related issue has come up here, which could also touch your use case: Constant scope definition · Issue #10281 · crystal-lang/crystal · GitHub