Browse Source

refactor(locale): simplify pluralForm

Instead of having a switch-case returning a function to be executed, it's
simpler/faster to have a single function containing a switch-case. It also
allows to group languages with identical plural form in a single
implementation, and remove the "default" guard value, as switch-case already
have a `default:` case.
jvoisin 9 months ago
parent
commit
dcfe0a7d94
3 changed files with 29 additions and 78 deletions
  1. 27 71
      internal/locale/plural.go
  2. 1 1
      internal/locale/plural_test.go
  3. 1 6
      internal/locale/printer.go

+ 27 - 71
internal/locale/plural.go

@@ -5,16 +5,9 @@ package locale // import "miniflux.app/v2/internal/locale"
 
 // See https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
 // And http://www.unicode.org/cldr/charts/29/supplemental/language_plural_rules.html
-var pluralForms = map[string]func(n int) int{
-	// nplurals=2; plural=(n != 1);
-	"default": func(n int) int {
-		if n != 1 {
-			return 1
-		}
-		return 0
-	},
-	// nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5);
-	"ar_AR": func(n int) int {
+func getPluralForm(lang string, n int) int {
+	switch lang {
+	case "ar_AR":
 		switch {
 		case n == 0:
 			return 0
@@ -26,90 +19,53 @@ var pluralForms = map[string]func(n int) int{
 			return 3
 		case n%100 >= 11:
 			return 4
+		default:
+			return 5
 		}
-		return 5
-	},
-	// nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;
-	"cs_CZ": func(n int) int {
+	case "cs_CZ":
 		switch {
 		case n == 1:
 			return 0
 		case n >= 2 && n <= 4:
 			return 1
+		default:
+			return 2
 		}
-		return 2
-	},
-	// nplurals=2; plural=(n > 1);
-	"fr_FR": func(n int) int {
-		if n > 1 {
-			return 1
-		}
+	case "id_ID", "ja_JP":
 		return 0
-	},
-	// nplurals=1; plural=0;
-	"id_ID": func(n int) int {
-		return 0
-	},
-	// nplurals=1; plural=0;
-	"ja_JP": func(n int) int {
-		return 0
-	},
-	// nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
-	"pl_PL": func(n int) int {
+	case "pl_PL":
 		switch {
 		case n == 1:
 			return 0
 		case n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20):
 			return 1
+		default:
+			return 2
 		}
-		return 2
-	},
-	// nplurals=2; plural=(n > 1);
-	"pt_BR": func(n int) int {
-		if n > 1 {
-			return 1
-		}
-		return 0
-	},
-	// nplurals=3; plural=(n==1 ? 0 : n==0 || (n%100 > 0 && n%100 < 20) ? 1 : 2);
-	"ro_RO": func(n int) int {
+	case "ro_RO":
 		switch {
 		case n == 1:
 			return 0
 		case n == 0 || (n%100 > 0 && n%100 < 20):
 			return 1
+		default:
+			return 2
 		}
-		return 2
-	},
-	"ru_RU": pluralFormRuSrUa,
-	// nplurals=2; plural=(n > 1);
-	"tr_TR": func(n int) int {
-		if n > 1 {
+	case "ru_RU", "uk_UA", "sr_RS":
+		switch {
+		case n%10 == 1 && n%100 != 11:
+			return 0
+		case n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20):
 			return 1
+		default:
+			return 2
 		}
+	case "zh_CN", "zh_TW", "nan_Latn_pehoeji":
 		return 0
-	},
-	"uk_UA": pluralFormRuSrUa,
-	"sr_RS": pluralFormRuSrUa,
-	// nplurals=1; plural=0;
-	"zh_CN": func(n int) int {
-		return 0
-	},
-	"zh_TW": func(n int) int {
-		return 0
-	},
-	"nan_Latn_pehoeji": func(n int) int {
-		return 0
-	},
-}
-
-// nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
-func pluralFormRuSrUa(n int) int {
-	switch {
-	case n%10 == 1 && n%100 != 11:
+	default: // includes fr_FR, pr_BR, tr_TR
+		if n > 1 {
+			return 1
+		}
 		return 0
-	case n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20):
-		return 1
 	}
-	return 2
 }

+ 1 - 1
internal/locale/plural_test.go

@@ -90,7 +90,7 @@ func TestPluralRules(t *testing.T) {
 
 	for rule, values := range scenarios {
 		for input, expected := range values {
-			result := pluralForms[rule](input)
+			result := getPluralForm(rule, input)
 			if result != expected {
 				t.Errorf(`Unexpected result for %q rule, got %d instead of %d for %d as input`, rule, result, expected, input)
 			}

+ 1 - 6
internal/locale/printer.go

@@ -57,12 +57,7 @@ func (p *Printer) Plural(key string, n int, args ...interface{}) string {
 			return key
 		}
 
-		pluralForm, found := pluralForms[p.language]
-		if !found {
-			pluralForm = pluralForms["default"]
-		}
-
-		index := pluralForm(n)
+		index := getPluralForm(p.language, n)
 		if len(plurals) > index {
 			return fmt.Sprintf(plurals[index], args...)
 		}