mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-25 01:00:16 -05:00
cty's new "refinements" concept allows us to reduce the range of unknown values from our functions. This initial changeset focuses only on declaring which functions are guaranteed to return a non-null result, which is a helpful baseline refinement because it allows "== null" and "!= null" tests to produce known results even when the given value is otherwise unknown. This commit also includes some updates to test results that are now refined based on cty's own built-in refinement behaviors, just as a result of us having updated cty in the previous commit.
138 lines
3.3 KiB
Go
138 lines
3.3 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package funcs
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/zclconf/go-cty/cty"
|
|
"github.com/zclconf/go-cty/cty/function"
|
|
)
|
|
|
|
// StartsWithFunc constructs a function that checks if a string starts with
|
|
// a specific prefix using strings.HasPrefix
|
|
var StartsWithFunc = function.New(&function.Spec{
|
|
Params: []function.Parameter{
|
|
{
|
|
Name: "str",
|
|
Type: cty.String,
|
|
},
|
|
{
|
|
Name: "prefix",
|
|
Type: cty.String,
|
|
},
|
|
},
|
|
Type: function.StaticReturnType(cty.Bool),
|
|
RefineResult: refineNotNull,
|
|
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
|
str := args[0].AsString()
|
|
prefix := args[1].AsString()
|
|
|
|
if strings.HasPrefix(str, prefix) {
|
|
return cty.True, nil
|
|
}
|
|
|
|
return cty.False, nil
|
|
},
|
|
})
|
|
|
|
// EndsWithFunc constructs a function that checks if a string ends with
|
|
// a specific suffix using strings.HasSuffix
|
|
var EndsWithFunc = function.New(&function.Spec{
|
|
Params: []function.Parameter{
|
|
{
|
|
Name: "str",
|
|
Type: cty.String,
|
|
},
|
|
{
|
|
Name: "suffix",
|
|
Type: cty.String,
|
|
},
|
|
},
|
|
Type: function.StaticReturnType(cty.Bool),
|
|
RefineResult: refineNotNull,
|
|
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
|
str := args[0].AsString()
|
|
suffix := args[1].AsString()
|
|
|
|
if strings.HasSuffix(str, suffix) {
|
|
return cty.True, nil
|
|
}
|
|
|
|
return cty.False, nil
|
|
},
|
|
})
|
|
|
|
// ReplaceFunc constructs a function that searches a given string for another
|
|
// given substring, and replaces each occurence with a given replacement string.
|
|
var ReplaceFunc = function.New(&function.Spec{
|
|
Params: []function.Parameter{
|
|
{
|
|
Name: "str",
|
|
Type: cty.String,
|
|
},
|
|
{
|
|
Name: "substr",
|
|
Type: cty.String,
|
|
},
|
|
{
|
|
Name: "replace",
|
|
Type: cty.String,
|
|
},
|
|
},
|
|
Type: function.StaticReturnType(cty.String),
|
|
RefineResult: refineNotNull,
|
|
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
|
str := args[0].AsString()
|
|
substr := args[1].AsString()
|
|
replace := args[2].AsString()
|
|
|
|
// We search/replace using a regexp if the string is surrounded
|
|
// in forward slashes.
|
|
if len(substr) > 1 && substr[0] == '/' && substr[len(substr)-1] == '/' {
|
|
re, err := regexp.Compile(substr[1 : len(substr)-1])
|
|
if err != nil {
|
|
return cty.UnknownVal(cty.String), err
|
|
}
|
|
|
|
return cty.StringVal(re.ReplaceAllString(str, replace)), nil
|
|
}
|
|
|
|
return cty.StringVal(strings.Replace(str, substr, replace, -1)), nil
|
|
},
|
|
})
|
|
|
|
// Replace searches a given string for another given substring,
|
|
// and replaces all occurences with a given replacement string.
|
|
func Replace(str, substr, replace cty.Value) (cty.Value, error) {
|
|
return ReplaceFunc.Call([]cty.Value{str, substr, replace})
|
|
}
|
|
|
|
// StrContainsFunc searches a given string for another given substring,
|
|
// if found the function returns true, otherwise returns false.
|
|
var StrContainsFunc = function.New(&function.Spec{
|
|
Params: []function.Parameter{
|
|
{
|
|
Name: "str",
|
|
Type: cty.String,
|
|
},
|
|
{
|
|
Name: "substr",
|
|
Type: cty.String,
|
|
},
|
|
},
|
|
Type: function.StaticReturnType(cty.Bool),
|
|
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
|
|
str := args[0].AsString()
|
|
substr := args[1].AsString()
|
|
|
|
if strings.Contains(str, substr) {
|
|
return cty.True, nil
|
|
}
|
|
|
|
return cty.False, nil
|
|
},
|
|
})
|