diff --git a/internal/template/funcmap.go b/internal/template/funcmap.go index 8d60bf53d..39ed13a76 100644 --- a/internal/template/funcmap.go +++ b/internal/template/funcmap.go @@ -36,6 +36,7 @@ var funcMap = map[string]interface{}{ "regexReplaceAll": regexReplaceAll, "makeSlice": makeSlice, "schemaDescription": schemaDescription, + "substr": substr, } // invalidIDRE defines the invalid characters not allowed in terraform resource names. @@ -156,3 +157,19 @@ func schemaDescription(s string) string { return fmt.Sprintf(`"%s"`, s) } + +// substr returns a substring that starts at index 'start' +// and spans 'length' characters (or until the end of the string, +// whichever comes first). +func substr(s string, start int, length int) (string, error) { + if start < 0 || start >= len(s) { + return "", fmt.Errorf("start index parameter has a invalid value: %d", start) + } + if length < 0 { + return "", fmt.Errorf("length parameter has a invalid value: %d", length) + } + if start+length > len(s) { + length = len(s) - start + } + return s[start : start+length], nil +} diff --git a/internal/template/template_test.go b/internal/template/template_test.go index c484300d6..3fa594b8d 100644 --- a/internal/template/template_test.go +++ b/internal/template/template_test.go @@ -298,3 +298,37 @@ func TestMakeSlice(t *testing.T) { } } } + +func TestSubstr(t *testing.T) { + tests := []struct { + input string + start, length int + want string + wantErr bool + }{ + {"sample string", -20, 0, "", true}, + {"sample string", 3, -3, "", true}, + {"sample string", 100, 4, "", true}, + {"sample string", 0, 40, "sample string", false}, + {"sample string", 0, 5, "sampl", false}, + {"sample string", 5, 4, "e st", false}, + {"sample string", 3, 0, "", false}, + } + for _, tc := range tests { + got, err := substr(tc.input, tc.start, tc.length) + + if err != nil && !tc.wantErr { + t.Fatalf("received error for valid input:\"%s\", start:%d, "+ + "length:%d, error received:\n%v", tc.input, tc.start, tc.length, err) + } + if err == nil && tc.wantErr { + t.Fatalf("did not receive error for invalid input: \"%s\", start:%d, "+ + "length:%d", tc.input, tc.start, tc.length) + } + + if diff := cmp.Diff(tc.want, got); diff != "" { + t.Errorf("substr results differ for input:\"%s\", start:%d, "+ + "length:%d and diff(-want +got):\n%v", tc.input, tc.start, tc.length, diff) + } + } +}