mirror of
https://github.com/GlueOps/autoglue.git
synced 2026-02-13 12:50:05 +01:00
210 lines
3.7 KiB
Go
210 lines
3.7 KiB
Go
package funcs
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"html/template"
|
|
"math"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
"unicode"
|
|
|
|
"golang.org/x/text/language"
|
|
"golang.org/x/text/message"
|
|
)
|
|
|
|
var printer = message.NewPrinter(language.English)
|
|
|
|
var TemplateFuncs = template.FuncMap{
|
|
// Time functions
|
|
"now": time.Now,
|
|
"timeSince": time.Since,
|
|
"timeUntil": time.Until,
|
|
"formatTime": formatTime,
|
|
"approxDuration": approxDuration,
|
|
|
|
// String functions
|
|
"uppercase": strings.ToUpper,
|
|
"lowercase": strings.ToLower,
|
|
"pluralize": pluralize,
|
|
"slugify": slugify,
|
|
"safeHTML": safeHTML,
|
|
|
|
// Slice functions
|
|
"join": strings.Join,
|
|
|
|
// Number functions
|
|
"incr": incr,
|
|
"decr": decr,
|
|
"formatInt": formatInt,
|
|
"formatFloat": formatFloat,
|
|
|
|
// Boolean functions
|
|
"yesno": yesno,
|
|
|
|
// URL functions
|
|
"urlSetParam": urlSetParam,
|
|
"urlDelParam": urlDelParam,
|
|
}
|
|
|
|
func formatTime(format string, t time.Time) string {
|
|
return t.Format(format)
|
|
}
|
|
|
|
func approxDuration(d time.Duration) string {
|
|
const (
|
|
day = 24 * time.Hour
|
|
year = 365 * day
|
|
)
|
|
|
|
formatUnit := func(count int, singular, plural string) string {
|
|
if count == 1 {
|
|
return fmt.Sprintf("1 %s", singular)
|
|
}
|
|
return fmt.Sprintf("%d %s", count, plural)
|
|
}
|
|
|
|
switch {
|
|
case d >= year:
|
|
return formatUnit(int(math.Round(float64(d)/float64(year))), "year", "years")
|
|
case d >= day:
|
|
return formatUnit(int(math.Round(float64(d)/float64(day))), "day", "days")
|
|
case d >= time.Hour:
|
|
return formatUnit(int(math.Round(d.Hours())), "hour", "hours")
|
|
case d >= time.Minute:
|
|
return formatUnit(int(math.Round(d.Minutes())), "minute", "minutes")
|
|
case d >= time.Second:
|
|
return formatUnit(int(math.Round(d.Seconds())), "second", "seconds")
|
|
default:
|
|
return "less than 1 second"
|
|
}
|
|
}
|
|
|
|
func pluralize(count any, singular string, plural string) (string, error) {
|
|
n, err := toInt64(count)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if n == 1 {
|
|
return singular, nil
|
|
}
|
|
|
|
return plural, nil
|
|
}
|
|
|
|
func slugify(s string) string {
|
|
var buf bytes.Buffer
|
|
|
|
for _, r := range s {
|
|
switch {
|
|
case r > unicode.MaxASCII:
|
|
continue
|
|
case unicode.IsLetter(r):
|
|
buf.WriteRune(unicode.ToLower(r))
|
|
case unicode.IsDigit(r), r == '_', r == '-':
|
|
buf.WriteRune(r)
|
|
case unicode.IsSpace(r):
|
|
buf.WriteRune('-')
|
|
}
|
|
}
|
|
|
|
return buf.String()
|
|
}
|
|
|
|
func safeHTML(s string) template.HTML {
|
|
return template.HTML(s)
|
|
}
|
|
|
|
func incr(i any) (int64, error) {
|
|
n, err := toInt64(i)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
n++
|
|
return n, nil
|
|
}
|
|
|
|
func decr(i any) (int64, error) {
|
|
n, err := toInt64(i)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
n--
|
|
return n, nil
|
|
}
|
|
|
|
func formatInt(i any) (string, error) {
|
|
n, err := toInt64(i)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return printer.Sprintf("%d", n), nil
|
|
}
|
|
|
|
func formatFloat(f float64, dp int) string {
|
|
format := "%." + strconv.Itoa(dp) + "f"
|
|
return printer.Sprintf(format, f)
|
|
}
|
|
|
|
func yesno(b bool) string {
|
|
if b {
|
|
return "Yes"
|
|
}
|
|
|
|
return "No"
|
|
}
|
|
|
|
func urlSetParam(u *url.URL, key string, value any) *url.URL {
|
|
nu := *u
|
|
values := nu.Query()
|
|
|
|
values.Set(key, fmt.Sprintf("%v", value))
|
|
|
|
nu.RawQuery = values.Encode()
|
|
return &nu
|
|
}
|
|
|
|
func urlDelParam(u *url.URL, key string) *url.URL {
|
|
nu := *u
|
|
values := nu.Query()
|
|
|
|
values.Del(key)
|
|
|
|
nu.RawQuery = values.Encode()
|
|
return &nu
|
|
}
|
|
|
|
func toInt64(i any) (int64, error) {
|
|
switch v := i.(type) {
|
|
case int:
|
|
return int64(v), nil
|
|
case int8:
|
|
return int64(v), nil
|
|
case int16:
|
|
return int64(v), nil
|
|
case int32:
|
|
return int64(v), nil
|
|
case int64:
|
|
return v, nil
|
|
case uint:
|
|
return int64(v), nil
|
|
case uint8:
|
|
return int64(v), nil
|
|
case uint16:
|
|
return int64(v), nil
|
|
case uint32:
|
|
return int64(v), nil
|
|
// Note: uint64 not supported due to risk of truncation.
|
|
case string:
|
|
return strconv.ParseInt(v, 10, 64)
|
|
}
|
|
|
|
return 0, fmt.Errorf("unable to convert type %T to int", i)
|
|
}
|