diff --git a/pkg/i18n/compose.go b/pkg/i18n/compose.go index 11534390..46337d52 100644 --- a/pkg/i18n/compose.go +++ b/pkg/i18n/compose.go @@ -27,53 +27,77 @@ func NewSubject(noun string, value any) *Subject { // Count sets the count for pluralization. // Used to determine singular/plural forms in templates. +// Panics if called on nil receiver; use S() to create subjects. // // S("file", files).Count(len(files)) func (s *Subject) Count(n int) *Subject { + if s == nil { + return nil + } s.count = n return s } // Gender sets the grammatical gender for languages that require it. // Common values: "masculine", "feminine", "neuter" +// Panics if called on nil receiver; use S() to create subjects. // // S("user", user).Gender("female") func (s *Subject) Gender(g string) *Subject { + if s == nil { + return nil + } s.gender = g return s } // In sets the location context for the subject. // Used in templates to provide spatial context. +// Panics if called on nil receiver; use S() to create subjects. // // S("file", "config.yaml").In("workspace") func (s *Subject) In(location string) *Subject { + if s == nil { + return nil + } s.location = location return s } // Formal sets the formality level to formal (Sie, vous, usted). // Use for polite/professional address in languages that distinguish formality. +// Panics if called on nil receiver; use S() to create subjects. // // S("colleague", name).Formal() func (s *Subject) Formal() *Subject { + if s == nil { + return nil + } s.formality = FormalityFormal return s } // Informal sets the formality level to informal (du, tu, tĂș). // Use for casual/friendly address in languages that distinguish formality. +// Panics if called on nil receiver; use S() to create subjects. // // S("friend", name).Informal() func (s *Subject) Informal() *Subject { + if s == nil { + return nil + } s.formality = FormalityInformal return s } // Formality sets the formality level explicitly. +// Panics if called on nil receiver; use S() to create subjects. // // S("user", name).Formality(FormalityFormal) func (s *Subject) Formality(f Formality) *Subject { + if s == nil { + return nil + } s.formality = f return s } @@ -94,41 +118,41 @@ func (s *Subject) IsPlural() bool { return s != nil && s.count != 1 } -// CountValue returns the count value. -func (s *Subject) CountValue() int { +// CountInt returns the count value. +func (s *Subject) CountInt() int { if s == nil { return 1 } return s.count } -// GenderValue returns the grammatical gender. -func (s *Subject) GenderValue() string { +// GenderString returns the grammatical gender. +func (s *Subject) GenderString() string { if s == nil { return "" } return s.gender } -// Location returns the location context. -func (s *Subject) Location() string { +// LocationString returns the location context. +func (s *Subject) LocationString() string { if s == nil { return "" } return s.location } -// NounValue returns the noun type. -func (s *Subject) NounValue() string { +// NounString returns the noun type. +func (s *Subject) NounString() string { if s == nil { return "" } return s.Noun } -// FormalityValue returns the formality level. +// FormalityString returns the formality level. // Returns FormalityNeutral if not explicitly set. -func (s *Subject) FormalityValue() Formality { +func (s *Subject) FormalityString() Formality { if s == nil { return FormalityNeutral } diff --git a/pkg/i18n/compose_test.go b/pkg/i18n/compose_test.go index c378e8d4..94e98400 100644 --- a/pkg/i18n/compose_test.go +++ b/pkg/i18n/compose_test.go @@ -33,26 +33,26 @@ func TestSubject_Good(t *testing.T) { t.Run("with count", func(t *testing.T) { s := S("file", "*.go").Count(5) - assert.Equal(t, 5, s.CountValue()) + assert.Equal(t, 5, s.CountInt()) assert.True(t, s.IsPlural()) }) t.Run("with gender", func(t *testing.T) { s := S("user", "alice").Gender("female") - assert.Equal(t, "female", s.GenderValue()) + assert.Equal(t, "female", s.GenderString()) }) t.Run("with location", func(t *testing.T) { s := S("file", "config.yaml").In("workspace") - assert.Equal(t, "workspace", s.Location()) + assert.Equal(t, "workspace", s.LocationString()) }) t.Run("chained methods", func(t *testing.T) { s := S("repo", "core-php").Count(3).Gender("neuter").In("organisation") - assert.Equal(t, "repo", s.NounValue()) - assert.Equal(t, 3, s.CountValue()) - assert.Equal(t, "neuter", s.GenderValue()) - assert.Equal(t, "organisation", s.Location()) + assert.Equal(t, "repo", s.NounString()) + assert.Equal(t, 3, s.CountInt()) + assert.Equal(t, "neuter", s.GenderString()) + assert.Equal(t, "organisation", s.LocationString()) }) } @@ -104,10 +104,10 @@ func TestSubject_IsPlural(t *testing.T) { func TestSubject_Getters(t *testing.T) { t.Run("nil safety", func(t *testing.T) { var s *Subject - assert.Equal(t, "", s.NounValue()) - assert.Equal(t, 1, s.CountValue()) - assert.Equal(t, "", s.GenderValue()) - assert.Equal(t, "", s.Location()) + assert.Equal(t, "", s.NounString()) + assert.Equal(t, 1, s.CountInt()) + assert.Equal(t, "", s.GenderString()) + assert.Equal(t, "", s.LocationString()) }) } @@ -193,31 +193,31 @@ func TestNewTemplateData(t *testing.T) { func TestSubject_Formality(t *testing.T) { t.Run("default is neutral", func(t *testing.T) { s := S("user", "name") - assert.Equal(t, FormalityNeutral, s.FormalityValue()) + assert.Equal(t, FormalityNeutral, s.FormalityString()) assert.False(t, s.IsFormal()) assert.False(t, s.IsInformal()) }) t.Run("Formal()", func(t *testing.T) { s := S("user", "name").Formal() - assert.Equal(t, FormalityFormal, s.FormalityValue()) + assert.Equal(t, FormalityFormal, s.FormalityString()) assert.True(t, s.IsFormal()) }) t.Run("Informal()", func(t *testing.T) { s := S("user", "name").Informal() - assert.Equal(t, FormalityInformal, s.FormalityValue()) + assert.Equal(t, FormalityInformal, s.FormalityString()) assert.True(t, s.IsInformal()) }) t.Run("Formality() explicit", func(t *testing.T) { s := S("user", "name").Formality(FormalityFormal) - assert.Equal(t, FormalityFormal, s.FormalityValue()) + assert.Equal(t, FormalityFormal, s.FormalityString()) }) t.Run("nil safety", func(t *testing.T) { var s *Subject - assert.Equal(t, FormalityNeutral, s.FormalityValue()) + assert.Equal(t, FormalityNeutral, s.FormalityString()) assert.False(t, s.IsFormal()) assert.False(t, s.IsInformal()) }) diff --git a/pkg/i18n/language.go b/pkg/i18n/language.go index d82f8b19..911c22c2 100644 --- a/pkg/i18n/language.go +++ b/pkg/i18n/language.go @@ -67,7 +67,8 @@ func IsRTLLanguage(lang string) bool { return false } -// English: one (n=1), other +// pluralRuleEnglish returns the plural category for English. +// Categories: one (n=1), other. func pluralRuleEnglish(n int) PluralCategory { if n == 1 { return PluralOne @@ -75,12 +76,14 @@ func pluralRuleEnglish(n int) PluralCategory { return PluralOther } -// German: same as English +// pluralRuleGerman returns the plural category for German. +// Categories: same as English. func pluralRuleGerman(n int) PluralCategory { return pluralRuleEnglish(n) } -// French: one (n=0,1), other +// pluralRuleFrench returns the plural category for French. +// Categories: one (n=0,1), other. func pluralRuleFrench(n int) PluralCategory { if n == 0 || n == 1 { return PluralOne @@ -88,7 +91,8 @@ func pluralRuleFrench(n int) PluralCategory { return PluralOther } -// Spanish: one (n=1), many (n=0 or n>=1000000), other +// pluralRuleSpanish returns the plural category for Spanish. +// Categories: one (n=1), other. func pluralRuleSpanish(n int) PluralCategory { if n == 1 { return PluralOne @@ -96,7 +100,8 @@ func pluralRuleSpanish(n int) PluralCategory { return PluralOther } -// Russian: one (n%10=1, n%100!=11), few (n%10=2-4, n%100!=12-14), many (others) +// pluralRuleRussian returns the plural category for Russian. +// Categories: one (n%10=1, n%100!=11), few (n%10=2-4, n%100!=12-14), many (others). func pluralRuleRussian(n int) PluralCategory { mod10 := n % 10 mod100 := n % 100 @@ -110,7 +115,8 @@ func pluralRuleRussian(n int) PluralCategory { return PluralMany } -// Polish: one (n=1), few (n%10=2-4, n%100!=12-14), many (others) +// pluralRulePolish returns the plural category for Polish. +// Categories: one (n=1), few (n%10=2-4, n%100!=12-14), many (others). func pluralRulePolish(n int) PluralCategory { if n == 1 { return PluralOne @@ -123,7 +129,8 @@ func pluralRulePolish(n int) PluralCategory { return PluralMany } -// Arabic: zero (n=0), one (n=1), two (n=2), few (n%100=3-10), many (n%100=11-99), other +// pluralRuleArabic returns the plural category for Arabic. +// Categories: zero (n=0), one (n=1), two (n=2), few (n%100=3-10), many (n%100=11-99), other. func pluralRuleArabic(n int) PluralCategory { if n == 0 { return PluralZero @@ -144,15 +151,20 @@ func pluralRuleArabic(n int) PluralCategory { return PluralOther } -// Chinese/Japanese/Korean: other (no plural distinction) +// pluralRuleChinese returns the plural category for Chinese. +// Categories: other (no plural distinction). func pluralRuleChinese(n int) PluralCategory { return PluralOther } +// pluralRuleJapanese returns the plural category for Japanese. +// Categories: other (no plural distinction). func pluralRuleJapanese(n int) PluralCategory { return PluralOther } +// pluralRuleKorean returns the plural category for Korean. +// Categories: other (no plural distinction). func pluralRuleKorean(n int) PluralCategory { return PluralOther }