package namer import ( "strings" "go-common/app/tool/gengo/types" ) var consonants = "bcdfghjklmnpqrsttvwxyz" type pluralNamer struct { // key is the case-sensitive type name, value is the case-insensitive // intended output. exceptions map[string]string finalize func(string) string } // NewPublicPluralNamer returns a namer that returns the plural form of the input // type's name, starting with a uppercase letter. func NewPublicPluralNamer(exceptions map[string]string) *pluralNamer { return &pluralNamer{exceptions, IC} } // NewPrivatePluralNamer returns a namer that returns the plural form of the input // type's name, starting with a lowercase letter. func NewPrivatePluralNamer(exceptions map[string]string) *pluralNamer { return &pluralNamer{exceptions, IL} } // NewAllLowercasePluralNamer returns a namer that returns the plural form of the input // type's name, with all letters in lowercase. func NewAllLowercasePluralNamer(exceptions map[string]string) *pluralNamer { return &pluralNamer{exceptions, strings.ToLower} } // Name returns the plural form of the type's name. If the type's name is found // in the exceptions map, the map value is returned. func (r *pluralNamer) Name(t *types.Type) string { singular := t.Name.Name var plural string var ok bool if plural, ok = r.exceptions[singular]; ok { return r.finalize(plural) } if len(singular) < 2 { return r.finalize(singular) } switch rune(singular[len(singular)-1]) { case 's', 'x', 'z': plural = esPlural(singular) case 'y': sl := rune(singular[len(singular)-2]) if isConsonant(sl) { plural = iesPlural(singular) } else { plural = sPlural(singular) } case 'h': sl := rune(singular[len(singular)-2]) if sl == 'c' || sl == 's' { plural = esPlural(singular) } else { plural = sPlural(singular) } case 'e': sl := rune(singular[len(singular)-2]) if sl == 'f' { plural = vesPlural(singular[:len(singular)-1]) } else { plural = sPlural(singular) } case 'f': plural = vesPlural(singular) default: plural = sPlural(singular) } return r.finalize(plural) } func iesPlural(singular string) string { return singular[:len(singular)-1] + "ies" } func vesPlural(singular string) string { return singular[:len(singular)-1] + "ves" } func esPlural(singular string) string { return singular + "es" } func sPlural(singular string) string { return singular + "s" } func isConsonant(char rune) bool { for _, c := range consonants { if char == c { return true } } return false }