package smstmpl import ( "fmt" "maps" "regexp" "slices" "strings" "github.com/therootcompany/golib/net/smsgw" ) var reUnmatchedVars = regexp.MustCompile(`(\{[^}]+\})`) func RenderMessages(messages []smsgw.Message) ([]smsgw.Message, error) { for i, message := range messages { rowIndex := i + 1 message.Text = ReplaceVar(message.Template, "Name", message.Name) keyIter := maps.Keys(message.Vars) keys := slices.Sorted(keyIter) for _, key := range keys { val := message.Vars[key] message.Text = ReplaceVar(message.Text, key, val) } if tmpls := reUnmatchedVars.FindAllString(message.Text, -1); len(tmpls) != 0 { return nil, &CSVWarn{ Index: rowIndex, Code: "UnmatchedVars", Message: fmt.Sprintf( "failing due to row %d (%s): leftover template variable(s): %s", rowIndex, message.Name, strings.Join(tmpls, " "), ), // Record: rec, } } messages[i] = message } // TODO XXX AJ makes sure the copy retains its Text return messages, nil } func ReplaceVar(text, key, val string) string { if val != "" { // No special treatment: // "Hey {+Name}," => "Hey Doe," // "Bob,{Name}" => "Bob,Doe" // "{Name-},Joe" => "Doe,Joe" // "Hi {-Name-}, Joe" => "Hi Doe, Joe" var reHasVar = regexp.MustCompile(fmt.Sprintf(`\{\+?%s-?\}`, regexp.QuoteMeta(key))) return reHasVar.ReplaceAllString(text, val) } var metaKey = regexp.QuoteMeta(key) // "Hey {+Name}," => "Hey ," var reEatNone = regexp.MustCompile(fmt.Sprintf(`\{\+%s\}`, metaKey)) text = reEatNone.ReplaceAllString(text, val) // "Bob,{Name};" => "Bob;" var reEatOneLeft = regexp.MustCompile(fmt.Sprintf(`.?\{%s\}`, metaKey)) text = reEatOneLeft.ReplaceAllString(text, val) // ",{Name-};Joe" => ",Joe" var reEatOneRight = regexp.MustCompile(fmt.Sprintf(`\{%s-\}.?`, metaKey)) text = reEatOneRight.ReplaceAllString(text, val) // "Hi {-Name-}, Joe" => "Hi Joe" var reEatOneBoth = regexp.MustCompile(fmt.Sprintf(`.?\{-%s-\}.?`, metaKey)) text = reEatOneBoth.ReplaceAllString(text, val) return text }