Add HumanString method
Please add generation of "HumanString" method to make enum items "names", which differs from code-name. Its helpful to change "Meaning" on items, without changing code-name
// ENUM(new,active)
type ClientStatus byte
func (x ClientStatus) HumanString() string {
switch x {
case ClientStatusNew:
return "Not approved"
case ClientStatusActive:
return "Allowed to work"
default:
return ""
}
}
If it's acceptable to have ClientStatus be a string, you can do this
// ENUM(
// new = "Not approved"
// active = "Allowed to work"
// )
type ClientStatus string
Otherwise you need to propose a way to specify the output of "HumanString".
IMO it's not clear what a "human string" is supposed to mean. You might want several different string representations of the same value depending on context, and I don't think just String and HumanString is going to map neatly onto that. If you want a method that returns a different string value from String(), you can always implement it yourself (use the exhaustive lint rule to be sure you have covered all values)
How about allowing the String representation of integer enums to be changed? Like this:
// ENUM(
// new=0, string="Not approved"
// active=1, string="Allowed to work"
// )
type ClientStatus byte
At the moment, I'm additionally creating template methods for "HumanString" and the request was to get rid of it.
But I think something similar to option // new=0, string="Not approved" would be correct, because option // new = "Not approved" leads to a change in the data type to a string.
If you think that the name "HumanString" doesn't sound very good, then I agree with you, it was a conventional name. Probably "Label" will be more correct and understandable.
// new=0, label="Not approved"
Sorry if there's confusion, I'm not a maintainer/contributor, I just saw the issue while posting my own.
@abice
@jonathangjertsen I agreed with your previous comments, which is why I didn't step in. Appreciate your help in that matter.
I still am unclear as to what situation these alternate names would be used. Is there a reason not to have those enum names be the same as the labels that you're creating?
I didn't realize before now that the enum names you specify don't have to be valid identifiers.
// ENUM(
// Not approved=0
// Allowed to work=1
// )
type ClientStatus byte
-->
const (
ClientStatusNotApproved ClientStatus = iota
ClientStatusAllowedToWork
)
and String returns whatever you put in the comment. So my suggestion for changing the string representation isn't needed
Situation:
"Labels" are needed so that they can be easily transferred to the user interface (frontend or GUI/TUI), so that you can give a list of acceptable values in the form of Key=Value with minimal programming. The labels will be convenient for preparing the text of "human-readable" errors, and much more, where not some kind of designation is needed, but something understandable to an ordinary person.
type ClientStatus byte
type ClientStatusForUI struct {
Status ClientStatus
Label string
}
func GetStatusesListForUI() (result []ClientStatusForUI) {
// If there is something generated that will give a similar ready-made structure,
// then this will also be very good. Like Values() or Names()
for _, v:= range ClientStatusValues() {
result = append(result, ClientStatusForUI{v, v.Label()}
}
return result
}
func ErrClientStatusInvalid(status ClientStatus ) error {
return fmt.Errorf("Status %s is invalid", status.Label())
}
@abice
At what point are you using the non human readable strings? Like mentioned before, you can use the human readable string as the enum, and this will still work.
If the label is not in pure Latin and is long, then the code looks bad. I would like to have short English-language identifiers.
// ENUM(
//Můj dlouhý název pro značku, další velmi dlouhý název
// )
type SomeStatus byte
//...
const (
SomeStatusMůjDlouhýNázevProZnačku SomeStatus = iota
SomeStatusDalšíVelmiDlouhýNázev
)
I won't insist any more. My colleagues and I always have a question about labels when we talk about generation for enumerations.
The label text can be changed without changing the IDs. This is a very important point.
@abice
Would you expect that json or any other marshaling is affected by this change? Or it's just a matter of adding a function for translating to some label, or alias, or display value?
I just need to know the use case so I can properly assess how to implement it. It might be that instead of me adding a one off functionality for your use case, that maybe I add a tagging structure similar to go, and then pass those tags into the templates (built in or custom) and you could have the template generate it for you instead of me doing it.
Does that make sense?
Yes, it's just a matter of adding a function to convert to some kind of label, alias, or display value. No influence on marshalling is required. Initially, one method was required that would return the item's label. I would not like to use templates for this.
It will probably be possible to get the slice []{value, label} from the template. The value=label map will probably end up in the generated code, or maked from template.