Allow glob pattern in placerholder matching

This commit is contained in:
Ingo Oppermann 2022-08-24 12:29:54 +03:00
parent fc42f93d26
commit e74149eed2
No known key found for this signature in database
GPG Key ID: 2AB32426E9DD229E
4 changed files with 44 additions and 9 deletions

View File

@ -4,6 +4,9 @@ import (
"github.com/gobwas/glob"
)
// Match returns whether the name matches the glob pattern, also considering
// one or several optionnal separator. An error is only returned if the pattern
// is invalid.
func Match(pattern, name string, separators ...rune) (bool, error) {
g, err := glob.Compile(pattern, separators...)
if err != nil {

View File

@ -84,6 +84,7 @@ func (config *Config) ResolvePlaceholders(r replace.Replacer) {
for i, option := range config.Options {
// Replace any known placeholders
option = r.Replace(option, "diskfs", "")
option = r.Replace(option, "fs:disk", "")
config.Options[i] = option
}
@ -98,6 +99,7 @@ func (config *Config) ResolvePlaceholders(r replace.Replacer) {
input.Address = r.Replace(input.Address, "reference", config.Reference)
input.Address = r.Replace(input.Address, "diskfs", "")
input.Address = r.Replace(input.Address, "memfs", "")
input.Address = r.Replace(input.Address, "fs:*", "")
input.Address = r.Replace(input.Address, "rtmp", "")
input.Address = r.Replace(input.Address, "srt", "")
@ -108,6 +110,7 @@ func (config *Config) ResolvePlaceholders(r replace.Replacer) {
option = r.Replace(option, "reference", config.Reference)
option = r.Replace(option, "diskfs", "")
option = r.Replace(option, "memfs", "")
option = r.Replace(option, "fs:*", "")
input.Options[j] = option
}
@ -124,6 +127,7 @@ func (config *Config) ResolvePlaceholders(r replace.Replacer) {
output.Address = r.Replace(output.Address, "reference", config.Reference)
output.Address = r.Replace(output.Address, "diskfs", "")
output.Address = r.Replace(output.Address, "memfs", "")
output.Address = r.Replace(output.Address, "fs:*", "")
output.Address = r.Replace(output.Address, "rtmp", "")
output.Address = r.Replace(output.Address, "srt", "")
@ -134,6 +138,7 @@ func (config *Config) ResolvePlaceholders(r replace.Replacer) {
option = r.Replace(option, "reference", config.Reference)
option = r.Replace(option, "diskfs", "")
option = r.Replace(option, "memfs", "")
option = r.Replace(option, "fs:*", "")
output.Options[j] = option
}

View File

@ -4,6 +4,8 @@ import (
"net/url"
"regexp"
"strings"
"github.com/datarhei/core/v16/glob"
)
type Replacer interface {
@ -24,7 +26,8 @@ type Replacer interface {
// the value of the corresponding key in the parameters.
// If the value is an empty string, the registered templates will be searched for that
// placeholder. If no template is found, the placeholder will be replaced by the empty string.
// A placeholder name may consist on of the letters a-z.
// A placeholder name may consist on of the letters a-z and ':'. The placeholder may contain
// a glob pattern to find the appropriate template.
Replace(str, placeholder, value string) string
}
@ -39,8 +42,8 @@ type replacer struct {
func New() Replacer {
r := &replacer{
templates: make(map[string]func() string),
re: regexp.MustCompile(`{([a-z]+)(?:\^(.))?(?:,(.*?))?}`),
templateRe: regexp.MustCompile(`{([a-z]+)}`),
re: regexp.MustCompile(`{([a-z:]+)(?:\^(.))?(?:,(.*?))?}`),
templateRe: regexp.MustCompile(`{([a-z:]+)}`),
}
return r
@ -57,7 +60,8 @@ func (r *replacer) RegisterTemplateFunc(placeholder string, template func() stri
func (r *replacer) Replace(str, placeholder, value string) string {
str = r.re.ReplaceAllStringFunc(str, func(match string) string {
matches := r.re.FindStringSubmatch(match)
if matches[1] != placeholder {
if ok, _ := glob.Match(placeholder, matches[1], ':'); !ok {
return match
}
@ -66,7 +70,7 @@ func (r *replacer) Replace(str, placeholder, value string) string {
// Check for a registered template
if len(v) == 0 {
tmplFunc, ok := r.templates[placeholder]
tmplFunc, ok := r.templates[matches[1]]
if ok {
v = tmplFunc()
}

View File

@ -34,15 +34,29 @@ func TestReplace(t *testing.T) {
func TestReplaceTemplate(t *testing.T) {
r := New()
r.RegisterTemplate("foobar", "Hello {who}! {what}?")
r.RegisterTemplate("foo:bar", "Hello {who}! {what}?")
replaced := r.Replace("{foobar,who=World}", "foobar", "")
replaced := r.Replace("{foo:bar,who=World}", "foo:bar", "")
require.Equal(t, "Hello World! {what}?", replaced)
replaced = r.Replace("{foobar,who=World,what=E%3dmc^2}", "foobar", "")
replaced = r.Replace("{foo:bar,who=World,what=E%3dmc^2}", "foo:bar", "")
require.Equal(t, "Hello World! E=mc^2?", replaced)
replaced = r.Replace("{foobar^:,who=World,what=E%3dmc:2}", "foobar", "")
replaced = r.Replace("{foo:bar^:,who=World,what=E%3dmc:2}", "foo:bar", "")
require.Equal(t, "Hello World! E=mc\\\\:2?", replaced)
}
func TestReplaceTemplateFunc(t *testing.T) {
r := New()
r.RegisterTemplateFunc("foo:bar", func() string { return "Hello {who}! {what}?" })
replaced := r.Replace("{foo:bar,who=World}", "foo:bar", "")
require.Equal(t, "Hello World! {what}?", replaced)
replaced = r.Replace("{foo:bar,who=World,what=E%3dmc^2}", "foo:bar", "")
require.Equal(t, "Hello World! E=mc^2?", replaced)
replaced = r.Replace("{foo:bar^:,who=World,what=E%3dmc:2}", "foo:bar", "")
require.Equal(t, "Hello World! E=mc\\\\:2?", replaced)
}
@ -62,3 +76,12 @@ func TestReplaceCompileTemplate(t *testing.T) {
require.Equal(t, e[2], replaced, e[0])
}
}
func TestReplaceGlob(t *testing.T) {
r := New()
r.RegisterTemplate("foo:bar", "Hello foobar")
r.RegisterTemplate("foo:baz", "Hello foobaz")
replaced := r.Replace("{foo:baz}, {foo:bar}", "foo:*", "")
require.Equal(t, "Hello foobaz, Hello foobar", replaced)
}