Allow defaults for template parameter
This commit is contained in:
parent
1a9ef8b7c9
commit
ee2a188be8
@ -9,12 +9,13 @@ import (
|
||||
type Replacer interface {
|
||||
// RegisterTemplate registers a template for a specific placeholder. Template
|
||||
// may contain placeholders as well of the form {name}. They will be replaced
|
||||
// by the parameters of the placeholder (see Replace).
|
||||
RegisterTemplate(placeholder, template string)
|
||||
// by the parameters of the placeholder (see Replace). If a parameter is not of
|
||||
// a template is not present, default values can be provided.
|
||||
RegisterTemplate(placeholder, template string, defaults map[string]string)
|
||||
|
||||
// RegisterTemplateFunc does the same as RegisterTemplate, but the template
|
||||
// is returned by the template function.
|
||||
RegisterTemplateFunc(placeholder string, template func() string)
|
||||
RegisterTemplateFunc(placeholder string, template func() string, defaults map[string]string)
|
||||
|
||||
// Replace replaces all occurences of placeholder in str with value. The placeholder is of the
|
||||
// form {placeholder}. It is possible to escape a characters in value with \\ by appending a ^
|
||||
@ -28,8 +29,13 @@ type Replacer interface {
|
||||
Replace(str, placeholder, value string) string
|
||||
}
|
||||
|
||||
type template struct {
|
||||
fn func() string
|
||||
defaults map[string]string
|
||||
}
|
||||
|
||||
type replacer struct {
|
||||
templates map[string]func() string
|
||||
templates map[string]template
|
||||
|
||||
re *regexp.Regexp
|
||||
templateRe *regexp.Regexp
|
||||
@ -38,7 +44,7 @@ type replacer struct {
|
||||
// New returns a Replacer
|
||||
func New() Replacer {
|
||||
r := &replacer{
|
||||
templates: make(map[string]func() string),
|
||||
templates: make(map[string]template),
|
||||
re: regexp.MustCompile(`{([a-z]+)(?:\^(.))?(?:,(.*?))?}`),
|
||||
templateRe: regexp.MustCompile(`{([a-z]+)}`),
|
||||
}
|
||||
@ -46,12 +52,18 @@ func New() Replacer {
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *replacer) RegisterTemplate(placeholder, template string) {
|
||||
r.templates[placeholder] = func() string { return template }
|
||||
func (r *replacer) RegisterTemplate(placeholder, tmpl string, defaults map[string]string) {
|
||||
r.templates[placeholder] = template{
|
||||
fn: func() string { return tmpl },
|
||||
defaults: defaults,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *replacer) RegisterTemplateFunc(placeholder string, template func() string) {
|
||||
r.templates[placeholder] = template
|
||||
func (r *replacer) RegisterTemplateFunc(placeholder string, tmplFn func() string, defaults map[string]string) {
|
||||
r.templates[placeholder] = template{
|
||||
fn: tmplFn,
|
||||
defaults: defaults,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *replacer) Replace(str, placeholder, value string) string {
|
||||
@ -63,16 +75,20 @@ func (r *replacer) Replace(str, placeholder, value string) string {
|
||||
|
||||
// We need a copy from the value
|
||||
v := value
|
||||
var tmpl template = template{
|
||||
fn: func() string { return v },
|
||||
}
|
||||
|
||||
// Check for a registered template
|
||||
if len(v) == 0 {
|
||||
tmplFunc, ok := r.templates[placeholder]
|
||||
t, ok := r.templates[placeholder]
|
||||
if ok {
|
||||
v = tmplFunc()
|
||||
tmpl = t
|
||||
}
|
||||
}
|
||||
|
||||
v = r.compileTemplate(v, matches[3])
|
||||
v = tmpl.fn()
|
||||
v = r.compileTemplate(v, matches[3], tmpl.defaults)
|
||||
|
||||
if len(matches[2]) != 0 {
|
||||
// If there's a character to escape, we also have to escape the
|
||||
@ -97,13 +113,18 @@ func (r *replacer) Replace(str, placeholder, value string) string {
|
||||
// placeholder name and will be replaced with the value. The resulting string is "Hello World!".
|
||||
// If a placeholder name is not present in the params string, it will not be replaced. The key
|
||||
// and values can be escaped as in net/url.QueryEscape.
|
||||
func (r *replacer) compileTemplate(str, params string) string {
|
||||
if len(params) == 0 {
|
||||
func (r *replacer) compileTemplate(str, params string, defaults map[string]string) string {
|
||||
if len(params) == 0 && len(defaults) == 0 {
|
||||
return str
|
||||
}
|
||||
|
||||
p := make(map[string]string)
|
||||
|
||||
// Copy the defaults
|
||||
for key, value := range defaults {
|
||||
p[key] = value
|
||||
}
|
||||
|
||||
// taken from net/url.ParseQuery
|
||||
for params != "" {
|
||||
var key string
|
||||
|
||||
@ -34,7 +34,7 @@ func TestReplace(t *testing.T) {
|
||||
|
||||
func TestReplaceTemplate(t *testing.T) {
|
||||
r := New()
|
||||
r.RegisterTemplate("foobar", "Hello {who}! {what}?")
|
||||
r.RegisterTemplate("foobar", "Hello {who}! {what}?", nil)
|
||||
|
||||
replaced := r.Replace("{foobar,who=World}", "foobar", "")
|
||||
require.Equal(t, "Hello World! {what}?", replaced)
|
||||
@ -46,6 +46,20 @@ func TestReplaceTemplate(t *testing.T) {
|
||||
require.Equal(t, "Hello World! E=mc\\\\:2?", replaced)
|
||||
}
|
||||
|
||||
func TestReplaceTemplateDefaults(t *testing.T) {
|
||||
r := New()
|
||||
r.RegisterTemplate("foobar", "Hello {who}! {what}?", map[string]string{
|
||||
"who": "someone",
|
||||
"what": "something",
|
||||
})
|
||||
|
||||
replaced := r.Replace("{foobar}", "foobar", "")
|
||||
require.Equal(t, "Hello someone! something?", replaced)
|
||||
|
||||
replaced = r.Replace("{foobar,who=World}", "foobar", "")
|
||||
require.Equal(t, "Hello World! something?", replaced)
|
||||
}
|
||||
|
||||
func TestReplaceCompileTemplate(t *testing.T) {
|
||||
samples := [][3]string{
|
||||
{"Hello {who}!", "who=World", "Hello World!"},
|
||||
@ -58,7 +72,27 @@ func TestReplaceCompileTemplate(t *testing.T) {
|
||||
r := New().(*replacer)
|
||||
|
||||
for _, e := range samples {
|
||||
replaced := r.compileTemplate(e[0], e[1])
|
||||
replaced := r.compileTemplate(e[0], e[1], nil)
|
||||
require.Equal(t, e[2], replaced, e[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestReplaceCompileTemplateDefaults(t *testing.T) {
|
||||
samples := [][3]string{
|
||||
{"Hello {who}!", "", "Hello someone!"},
|
||||
{"Hello {who}!", "who=World", "Hello World!"},
|
||||
{"Hello {who}! {what}?", "who=World", "Hello World! something?"},
|
||||
{"Hello {who}! {what}?", "who=World,what=Yeah", "Hello World! Yeah?"},
|
||||
{"Hello {who}! {what}?", "who=World,what=", "Hello World! ?"},
|
||||
}
|
||||
|
||||
r := New().(*replacer)
|
||||
|
||||
for _, e := range samples {
|
||||
replaced := r.compileTemplate(e[0], e[1], map[string]string{
|
||||
"who": "someone",
|
||||
"what": "something",
|
||||
})
|
||||
require.Equal(t, e[2], replaced, e[0])
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user