Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String-based Enums types #2978

Closed
chendo opened this issue Jul 11, 2016 · 7 comments
Closed

String-based Enums types #2978

chendo opened this issue Jul 11, 2016 · 7 comments

Comments

@chendo
Copy link

chendo commented Jul 11, 2016

I'd like to have the ability to have String based Enums. My current use case is I'm using JSON.mapping to turn JSON output into typed classes, but I'd like the ability to do something like this:

enum EventType : String
  Pending = "PENDING"
  InProgress = "IN_PROGRESS"
  Complete = "COMPLETE"
end

struct Event
  JSON.mapping({
     name: String,
     event_type: EventType
  })
end

I'm not sure how a event_type value that doesn't match should work, maybe some sort of catch all EventType::Other like how there's All and None for the integer ones?

Thoughts?

@bcardiff
Copy link
Member

I would suggest using a formatter for converting the string to symbols.

@chendo
Copy link
Author

chendo commented Jul 11, 2016

I'd like to be able use types to mitigate errors so I can catch typos easily.

For example:

Event.create(name: "Foo", type: Pending)

The other option is to write my own struct that I can subclass and do that, but Enum seems like a better fit for this.

@ysbaddaden
Copy link
Contributor

Enum#new(JSON::PullParser) accepts both an Integer (the enum value) or a String (the enum key), so you may just override the to_json(io) method to output the key instead of the value and you'll have it working as you expect; you'll just have upcased keys:

require "json"

enum EventType
  PENDING = 1
  IN_PROGRESS = 2
  COMPLETE = 3

  def to_json(io)
    io << '"'
    to_s(io)
    io << '"'
  end
end

struct MyEvent
  JSON.mapping({
    name: String,
    event_type: EventType,
  })
end

p event = MyEvent.from_json("{ \"name\": \"blabla\", \"event_type\": \"PENDING\" }")
# => MyEvent(@name="blabla", @event_type=PENDING)

puts event.to_json
# => {"name":"blabla","event_type":"PENDING"}

@david50407
Copy link
Contributor

david50407 commented Jul 16, 2016

enum is Value type but String is a Reference so I think that is hard to enum a String?

BTW, if we can provide the convert rules in JSON.mapping (like giving a NamedTuple?) will be better.

Edited: like

struct MyEvent
  JSON.mapping({
    name: String,
    event_type: {PENDING: :foo, IN_PROGRESS: :bar}
  })
end

p event = MyEvent.from_json("{ \"name\": \"blabla\", \"event_type\": \"PENDING\" }")
# => MyEvent(@name="blabla", @event_type=:foo)

puts event.to_json
# => {"name":"blabla","event_type":"PENDING"}

@spalladino spalladino removed the RFC label Jan 9, 2017
@akzhan
Copy link
Contributor

akzhan commented Jun 20, 2017

I believe that this issue should be closed as "status:wantfix".

@straight-shoota
Copy link
Member

The example from @ysbaddaden shows, that the intended result can already be achieved in a different way.

BTW to_json is even simple nowadays: builder.string self

@asterite
Copy link
Member

Let's close this. Enums need an integer value. For a string representation the solutions above are good enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants