2018-10-29 22:57:39 +02:00
|
|
|
package strings
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"regexp"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/MontFerret/ferret/pkg/runtime/core"
|
|
|
|
"github.com/MontFerret/ferret/pkg/runtime/values"
|
2019-02-13 19:31:18 +02:00
|
|
|
"github.com/MontFerret/ferret/pkg/runtime/values/types"
|
2018-10-29 22:57:39 +02:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Fmt formats the template using these arguments.
|
|
|
|
// @params template (String) - template.
|
|
|
|
// @params args (Any Values) - template arguments.
|
|
|
|
// @returns (String) - string formed by template using arguments.
|
|
|
|
func Fmt(_ context.Context, args ...core.Value) (core.Value, error) {
|
|
|
|
err := core.ValidateArgs(args, 1, core.MaxArgs)
|
|
|
|
if err != nil {
|
|
|
|
return values.None, err
|
|
|
|
}
|
|
|
|
|
2019-02-13 19:31:18 +02:00
|
|
|
err = core.ValidateType(args[0], types.String)
|
2018-10-29 22:57:39 +02:00
|
|
|
if err != nil {
|
|
|
|
return values.None, err
|
|
|
|
}
|
|
|
|
|
|
|
|
formatted, err := format(args[0].String(), args[1:])
|
|
|
|
if err != nil {
|
|
|
|
return values.None, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return values.NewString(formatted), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func format(template string, args []core.Value) (string, error) {
|
2019-03-29 16:48:51 +02:00
|
|
|
rgx := regexp.MustCompile("{[0-9]*}")
|
2018-10-29 22:57:39 +02:00
|
|
|
|
|
|
|
argsCount := len(args)
|
|
|
|
emptyBracketsCount := strings.Count(template, "{}")
|
|
|
|
|
|
|
|
if argsCount > emptyBracketsCount && emptyBracketsCount != 0 {
|
|
|
|
return "", errors.Errorf("there are arguments that have never been used")
|
|
|
|
}
|
|
|
|
|
|
|
|
var betweenBrackets string
|
|
|
|
var n int
|
|
|
|
// index of the last value
|
|
|
|
// inserted into the template
|
|
|
|
var lastArgIdx int
|
2019-03-29 16:48:51 +02:00
|
|
|
var err error
|
2018-10-29 22:57:39 +02:00
|
|
|
|
|
|
|
template = rgx.ReplaceAllStringFunc(template, func(s string) string {
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
betweenBrackets = s[1 : len(s)-1]
|
|
|
|
|
|
|
|
if betweenBrackets == "" {
|
|
|
|
if argsCount <= lastArgIdx {
|
2020-02-02 06:44:31 +02:00
|
|
|
err = errors.Errorf("not enough arguments")
|
2018-10-29 22:57:39 +02:00
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
lastArgIdx++
|
|
|
|
return args[lastArgIdx-1].String()
|
|
|
|
}
|
|
|
|
|
|
|
|
n, err = strconv.Atoi(betweenBrackets)
|
|
|
|
if err != nil {
|
|
|
|
err = errors.Errorf("failed to parse int: %v", err)
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
if n >= argsCount {
|
|
|
|
err = errors.Errorf("invalid reference to argument `%d`", n)
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return args[n].String()
|
|
|
|
})
|
|
|
|
|
|
|
|
return template, err
|
|
|
|
}
|