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

EnumSpec: Add support for MustUnmarshalText function #343

Closed
hlin117 opened this issue Feb 21, 2018 · 5 comments
Closed

EnumSpec: Add support for MustUnmarshalText function #343

hlin117 opened this issue Feb 21, 2018 · 5 comments

Comments

@hlin117
Copy link
Contributor

hlin117 commented Feb 21, 2018

#309 implemented the encoding.Unmarshaler so []byte types can be converted into enum values. For example, this function can now be generated.

// UnmarshalText tries to decode ImpressionType from a byte slice
// containing its name.
//
//   var v ImpressionType
//   err := v.UnmarshalText([]byte("OPENED"))
func (v *ImpressionType) UnmarshalText(value []byte) error {
	switch string(value) {
	case "OPENED":
		*v = ImpressionTypeOpened
		return nil
	case "COMPLETED":
		*v = ImpressionTypeCompleted
		return nil
	default:
		return fmt.Errorf("unknown enum value %q for %q", value, "ImpressionType")
	}
}

It would be nice if an additional mapper, MustUnmarshalText, were implemented, like so:

func (v *ImpressionType) MustUnmarshalText(value []byte) {
    if err := v.UnmarshalText(value); err != nil {
        panic(err)
    }
}

Related: #134

@abhinav
Copy link
Contributor

abhinav commented Feb 21, 2018

The UnmarshalText method was implemented to satisfy the encoding.TextUnmarshaler interface.

I would prefer not to generate functions that panic-by-default, especially in
this case where panicing in the caller is pretty easy.

@hlin117
Copy link
Contributor Author

hlin117 commented Feb 21, 2018

I would prefer not to generate functions that panic-by-default, especially in
this case where panicing in the caller is pretty easy.

That's fair. My use case is we have a datastore which stores the enums as a string representation. So we know that these strings will translate perfectly into an enum value.

@abhinav
Copy link
Contributor

abhinav commented Feb 21, 2018

You don't necessarily have that guarantee because additions to the enum won't
propagate to all instances of your service at the same time.

Suppose you add a new enum entry and deploy the change. While the deployment
is in flight, one of the upgraded instances of your service processes a
request and puts the value in the database. Another instance that has not yet
upgraded ends up reading that entry from the database and doesn't know what it
means.

You always want to have a catch-all case. It can return an error upstream
rather than causing your service to crash with a panic.

@kriskowal
Copy link
Contributor

@hlin117 have you considered the case of retrieving a string from the database, with a client that was generated with an older version of the IDL and does not recognize the string? If the database stores the underlying number (perhaps alongside the string for human readers), old clients would be able to deserialize the value regardless of whether it is known to the version of the client.

@hlin117
Copy link
Contributor Author

hlin117 commented Feb 21, 2018

You two are right; serialization does get tricky if there are IDL inconsistencies between two instances of the service.

Given these cases, I'm willing to close this issue as is. Thanks for your feedback!

@hlin117 hlin117 closed this as completed Feb 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants