diff --git a/flect_test.go b/flect_test.go index 848d77a..4ab6251 100644 --- a/flect_test.go +++ b/flect_test.go @@ -322,6 +322,28 @@ var singlePluralAssertions = []dict{ {"waste", "wastes", true, true}, {"psi", "psis", true, true}, {"pepsi", "pepsis", true, true}, + + // Acronyms + {"widget_uuid", "widget_uuids", true, true}, + {"WidgetUUID", "WidgetUUIDs", true, true}, + {"widgetUUID", "widgetUUIDs", true, true}, + {"widgetUuid", "widgetUuids", true, true}, + {"widget_UUID", "widget_UUIDs", true, true}, + + {"ID", "IDs", true, true}, + {"IDS", "IDSes", true, true}, + // id to ids (ID), ids to idses (IDS) is not supported + {"api", "apis", true, true}, + {"API", "APIs", true, true}, + {"html", "htmls", true, true}, + {"HTML", "HTMLs", true, true}, + {"FYI", "FYIs", true, true}, + {"LAN", "LANs", true, true}, + {"ssh", "sshs", true, true}, // sh + {"SSH", "SSHs", true, true}, + {"eia", "eias", true, true}, // ia + {"EIA", "EIAs", true, true}, + {"DNS", "DNSes", true, true}, } func init() { diff --git a/plural_rules.go b/plural_rules.go index 53c6081..3904e79 100644 --- a/plural_rules.go +++ b/plural_rules.go @@ -202,6 +202,9 @@ var dictionary = []word{ {singular: "shoe", plural: "shoes"}, {singular: "toe", plural: "toes", exact: true}, {singular: "graffiti", plural: "graffiti"}, + + // abbreviations + {singular: "ID", plural: "IDs", exact: true}, } // singleToPlural is the highest priority map for Pluralize(). @@ -366,6 +369,9 @@ var singularToPluralSuffixList = []singularToPluralSuffix{ {"o", "oes"}, {"x", "xes"}, + // for abbreviations + {"S", "Ses"}, + // excluded rules: seems rare // Words from Hebrew that add -im or -ot (eg, cherub becomes cherubim) // - cherub (cherubs or cherubim), seraph (seraphs or seraphim) diff --git a/pluralize.go b/pluralize.go index a983f72..d0ac77d 100644 --- a/pluralize.go +++ b/pluralize.go @@ -38,6 +38,14 @@ func (i Ident) Pluralize() Ident { pluralMoot.RLock() defer pluralMoot.RUnlock() + // check if the Original has an explicit entry in the map + if p, ok := singleToPlural[i.Original]; ok { + return i.ReplaceSuffix(i.Original, p) + } + if _, ok := pluralToSingle[i.Original]; ok { + return i + } + ls := strings.ToLower(s) if _, ok := pluralToSingle[ls]; ok { return i @@ -51,7 +59,7 @@ func (i Ident) Pluralize() Ident { } for _, r := range pluralRules { - if strings.HasSuffix(ls, r.suffix) { + if strings.HasSuffix(s, r.suffix) { return i.ReplaceSuffix(s, r.fn(s)) } } diff --git a/singularize.go b/singularize.go index 9993d65..d00cf4f 100644 --- a/singularize.go +++ b/singularize.go @@ -35,6 +35,14 @@ func (i Ident) Singularize() Ident { singularMoot.RLock() defer singularMoot.RUnlock() + // check if the Original has an explicit entry in the map + if p, ok := pluralToSingle[i.Original]; ok { + return i.ReplaceSuffix(i.Original, p) + } + if _, ok := singleToPlural[i.Original]; ok { + return i + } + ls := strings.ToLower(s) if p, ok := pluralToSingle[ls]; ok { if s == Capitalize(s) { @@ -48,7 +56,7 @@ func (i Ident) Singularize() Ident { } for _, r := range singularRules { - if strings.HasSuffix(ls, r.suffix) { + if strings.HasSuffix(s, r.suffix) { return i.ReplaceSuffix(s, r.fn(s)) } }