feature/plural: expose low-level plural matcher

Oftentimes the plural form can be exposed without
computing the intermediate number representation.
Allow this.

Change-Id: I6b8819bd175bd5ab1a7e9a9395448fa5c9b4274b
Reviewed-on: https://go-review.googlesource.com/58430
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/feature/plural/plural.go b/feature/plural/plural.go
index 7273091..dc34b47 100644
--- a/feature/plural/plural.go
+++ b/feature/plural/plural.go
@@ -144,6 +144,25 @@
 	return matchPlural(p, index, n, f, scale)
 }
 
+// MatchPlural returns the plural form for the given language and plural
+// operands (as defined in
+// http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules):
+//  where
+//  	n  absolute value of the source number (integer and decimals)
+//  input
+//  	i  integer digits of n.
+//  	v  number of visible fraction digits in n, with trailing zeros.
+//  	w  number of visible fraction digits in n, without trailing zeros.
+//  	f  visible fractional digits in n, with trailing zeros (f = t * 10^(v-w))
+//  	t  visible fractional digits in n, without trailing zeros.
+//
+// If any of the operand values is too large to fit in an int, it is okay to
+// pass the value modulo 10,000,000.
+func (p *Rules) MatchPlural(lang language.Tag, i, v, w, f, t int) Form {
+	index, _ := language.CompactIndex(lang)
+	return matchPlural(p, index, i, f, v)
+}
+
 func matchPlural(p *Rules, index int, n, f, v int) Form {
 	nMask := p.inclusionMasks[n%maxMod]
 	// Compute the fMask inline in the rules below, as it is relatively rare.
diff --git a/feature/plural/plural_test.go b/feature/plural/plural_test.go
index 2b30e9d..b3cf4c4 100644
--- a/feature/plural/plural_test.go
+++ b/feature/plural/plural_test.go
@@ -141,6 +141,16 @@
 					num := fmt.Sprintf("%[1]d.%0[3]*[2]d", n/m, n%m, scale)
 					name := fmt.Sprintf("%s:dec(%s)", loc, num)
 					t.Run(name, func(t *testing.T) {
+						ff := n % m
+						tt := ff
+						w := scale
+						for tt > 0 && tt%10 == 0 {
+							w--
+							tt /= 10
+						}
+						if f := p.MatchPlural(tag, n/m, scale, w, ff, tt); f != Form(tc.form) {
+							t.Errorf("MatchPlural: got %v; want %v", f, Form(tc.form))
+						}
 						if f := p.matchComponents(tag, n/m, n%m, scale); f != Form(tc.form) {
 							t.Errorf("matchComponents: got %v; want %v", f, Form(tc.form))
 						}