You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.5 KiB
104 lines
2.5 KiB
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 |
|
}
|
|
|