diff --git a/compose.go b/compose.go index 5e53dd0..0162846 100644 --- a/compose.go +++ b/compose.go @@ -10,6 +10,23 @@ func S(noun string, value any) *Subject { return &Subject{Noun: noun, Value: value, count: 1} } +// ComposeIntent renders an intent's templates into concrete output. +func ComposeIntent(intent Intent, subject *Subject) Composed { + return intent.Compose(subject) +} + +// Compose renders an intent's templates into concrete output. +func (i Intent) Compose(subject *Subject) Composed { + data := newTemplateData(subject) + return Composed{ + Question: executeIntentTemplate(i.Question, data), + Confirm: executeIntentTemplate(i.Confirm, data), + Success: executeIntentTemplate(i.Success, data), + Failure: executeIntentTemplate(i.Failure, data), + Meta: i.Meta, + } +} + func (s *Subject) Count(n int) *Subject { if s == nil { return nil @@ -68,12 +85,37 @@ func (s *Subject) String() string { return fmt.Sprint(s.Value) } -func (s *Subject) IsPlural() bool { return s != nil && s.count != 1 } -func (s *Subject) CountInt() int { if s == nil { return 1 }; return s.count } -func (s *Subject) CountString() string { if s == nil { return "1" }; return fmt.Sprint(s.count) } -func (s *Subject) GenderString() string { if s == nil { return "" }; return s.gender } -func (s *Subject) LocationString() string { if s == nil { return "" }; return s.location } -func (s *Subject) NounString() string { if s == nil { return "" }; return s.Noun } +func (s *Subject) IsPlural() bool { return s != nil && s.count != 1 } +func (s *Subject) CountInt() int { + if s == nil { + return 1 + } + return s.count +} +func (s *Subject) CountString() string { + if s == nil { + return "1" + } + return fmt.Sprint(s.count) +} +func (s *Subject) GenderString() string { + if s == nil { + return "" + } + return s.gender +} +func (s *Subject) LocationString() string { + if s == nil { + return "" + } + return s.location +} +func (s *Subject) NounString() string { + if s == nil { + return "" + } + return s.Noun +} func (s *Subject) FormalityString() string { if s == nil { return FormalityNeutral.String() diff --git a/i18n_test.go b/i18n_test.go index 965c87b..d9a8494 100644 --- a/i18n_test.go +++ b/i18n_test.go @@ -293,6 +293,43 @@ func TestExecuteIntentTemplate_Good_WithFuncs(t *testing.T) { assert.Equal(t, "built!", got) } +func TestComposeIntent_Good(t *testing.T) { + intent := Intent{ + Meta: IntentMeta{ + Type: "action", + Verb: "delete", + Dangerous: true, + Default: "no", + Supports: []string{"yes", "no"}, + }, + Question: "Delete {{.Subject}}?", + Confirm: "Really delete {{article .Subject}}?", + Success: "{{title .Subject}} deleted", + Failure: "Failed to delete {{lower .Subject}}", + } + + got := ComposeIntent(intent, S("file", "config.yaml")) + + assert.Equal(t, "Delete config.yaml?", got.Question) + assert.Equal(t, "Really delete a config.yaml?", got.Confirm) + assert.Equal(t, "Config.yaml deleted", got.Success) + assert.Equal(t, "Failed to delete config.yaml", got.Failure) + assert.Equal(t, intent.Meta, got.Meta) +} + +func TestIntentCompose_Good_NilSubject(t *testing.T) { + intent := Intent{ + Question: "Proceed?", + } + + got := intent.Compose(nil) + + assert.Equal(t, "Proceed?", got.Question) + assert.Empty(t, got.Confirm) + assert.Empty(t, got.Success) + assert.Empty(t, got.Failure) +} + // --- applyTemplate --- func TestApplyTemplate_Good(t *testing.T) {