singularize.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package flect
  2. import (
  3. "strings"
  4. "sync"
  5. )
  6. var singularMoot = &sync.RWMutex{}
  7. // Singularize returns a singular version of the string
  8. // users = user
  9. // data = datum
  10. // people = person
  11. func Singularize(s string) string {
  12. return New(s).Singularize().String()
  13. }
  14. // SingularizeWithSize will singular a string taking a number number into account.
  15. // SingularizeWithSize("user", 1) = user
  16. // SingularizeWithSize("user", 2) = users
  17. func SingularizeWithSize(s string, i int) string {
  18. return PluralizeWithSize(s, i)
  19. }
  20. // Singularize returns a singular version of the string
  21. // users = user
  22. // data = datum
  23. // people = person
  24. func (i Ident) Singularize() Ident {
  25. s := i.LastPart()
  26. if len(s) == 0 {
  27. return i
  28. }
  29. singularMoot.RLock()
  30. defer singularMoot.RUnlock()
  31. // check if the Original has an explicit entry in the map
  32. if p, ok := pluralToSingle[i.Original]; ok {
  33. return i.ReplaceSuffix(i.Original, p)
  34. }
  35. if _, ok := singleToPlural[i.Original]; ok {
  36. return i
  37. }
  38. ls := strings.ToLower(s)
  39. if p, ok := pluralToSingle[ls]; ok {
  40. if s == Capitalize(s) {
  41. p = Capitalize(p)
  42. }
  43. return i.ReplaceSuffix(s, p)
  44. }
  45. if _, ok := singleToPlural[ls]; ok {
  46. return i
  47. }
  48. for _, r := range singularRules {
  49. if strings.HasSuffix(s, r.suffix) {
  50. return i.ReplaceSuffix(s, r.fn(s))
  51. }
  52. }
  53. if strings.HasSuffix(s, "s") {
  54. return i.ReplaceSuffix("s", "")
  55. }
  56. return i
  57. }