本文整理匯總了Golang中github.com/hashicorp/hil.Parse函數的典型用法代碼示例。如果您正苦於以下問題:Golang Parse函數的具體用法?Golang Parse怎麽用?Golang Parse使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了Parse函數的13個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: Example_variables
func Example_variables() {
input := "${var.test} - ${6 + 2}"
tree, err := hil.Parse(input)
if err != nil {
log.Fatal(err)
}
config := &hil.EvalConfig{
GlobalScope: &ast.BasicScope{
VarMap: map[string]ast.Variable{
"var.test": ast.Variable{
Type: ast.TypeString,
Value: "TEST STRING",
},
},
},
}
result, err := hil.Eval(tree, config)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Type: %s\n", result.Type)
fmt.Printf("Value: %s\n", result.Value)
// Output:
// Type: TypeString
// Value: TEST STRING - 8
}
示例2: Compile
// Compile validates a prepared query template and returns an opaque compiled
// object that can be used later to render the template.
func Compile(query *structs.PreparedQuery) (*CompiledTemplate, error) {
// Make sure it's a type we understand.
if query.Template.Type != structs.QueryTemplateTypeNamePrefixMatch {
return nil, fmt.Errorf("Bad Template.Type '%s'", query.Template.Type)
}
// Start compile.
ct := &CompiledTemplate{
trees: make(map[string]ast.Node),
}
// Make a copy of the query to use as the basis for rendering later.
dup, err := copystructure.Copy(query)
if err != nil {
return nil, err
}
var ok bool
ct.query, ok = dup.(*structs.PreparedQuery)
if !ok {
return nil, fmt.Errorf("Failed to copy query")
}
// Walk over all the string fields in the Service sub-structure and
// parse them as HIL.
parse := func(path string, v reflect.Value) error {
tree, err := hil.Parse(v.String())
if err != nil {
return fmt.Errorf("Bad format '%s' in Service%s: %s", v.String(), path, err)
}
ct.trees[path] = tree
return nil
}
if err := walk(&ct.query.Service, parse); err != nil {
return nil, err
}
// If they supplied a regexp then compile it.
if ct.query.Template.Regexp != "" {
var err error
ct.re, err = regexp.Compile(ct.query.Template.Regexp)
if err != nil {
return nil, fmt.Errorf("Bad Regexp: %s", err)
}
}
// Finally do a test render with the supplied name prefix. This will
// help catch errors before run time, and this is the most minimal
// prefix it will be expected to run with. The results might not make
// sense and create a valid service to lookup, but it should render
// without any errors.
if _, err = ct.Render(ct.query.Name); err != nil {
return nil, err
}
return ct, nil
}
示例3: TestDetectVariables
func TestDetectVariables(t *testing.T) {
cases := []struct {
Input string
Result []InterpolatedVariable
}{
{
"foo $${var.foo}",
nil,
},
{
"foo ${var.foo}",
[]InterpolatedVariable{
&UserVariable{
Name: "foo",
key: "var.foo",
},
},
},
{
"foo ${var.foo} ${var.bar}",
[]InterpolatedVariable{
&UserVariable{
Name: "foo",
key: "var.foo",
},
&UserVariable{
Name: "bar",
key: "var.bar",
},
},
},
}
for _, tc := range cases {
ast, err := hil.Parse(tc.Input)
if err != nil {
t.Fatalf("%s\n\nInput: %s", err, tc.Input)
}
actual, err := DetectVariables(ast)
if err != nil {
t.Fatalf("err: %s", err)
}
if !reflect.DeepEqual(actual, tc.Result) {
t.Fatalf("bad: %#v\n\nInput: %s", actual, tc.Input)
}
}
}
示例4: execute
// execute parses and executes a template using vars.
func execute(s string, vars map[string]interface{}) (string, error) {
root, err := hil.Parse(s)
if err != nil {
return "", err
}
varmap := make(map[string]ast.Variable)
for k, v := range vars {
// As far as I can tell, v is always a string.
// If it's not, tell the user gracefully.
s, ok := v.(string)
if !ok {
return "", fmt.Errorf("unexpected type for variable %q: %T", k, v)
}
// Store the defaults (string and value)
var val interface{} = s
typ := ast.TypeString
// If we can parse a float, then use that
if v, err := strconv.ParseFloat(s, 64); err == nil {
val = v
typ = ast.TypeFloat
}
varmap[k] = ast.Variable{
Value: val,
Type: typ,
}
}
cfg := hil.EvalConfig{
GlobalScope: &ast.BasicScope{
VarMap: varmap,
FuncMap: config.Funcs(),
},
}
result, err := hil.Eval(root, &cfg)
if err != nil {
return "", err
}
if result.Type != hil.TypeString {
return "", fmt.Errorf("unexpected output hil.Type: %v", result.Type)
}
return result.Value.(string), nil
}
示例5: testFunction
func testFunction(t *testing.T, config testFunctionConfig) {
for i, tc := range config.Cases {
ast, err := hil.Parse(tc.Input)
if err != nil {
t.Fatalf("Case #%d: input: %#v\nerr: %s", i, tc.Input, err)
}
result, err := hil.Eval(ast, langEvalConfig(config.Vars))
if err != nil != tc.Error {
t.Fatalf("Case #%d:\ninput: %#v\nerr: %s", i, tc.Input, err)
}
if !reflect.DeepEqual(result.Value, tc.Result) {
t.Fatalf("%d: bad output for input: %s\n\nOutput: %#v\nExpected: %#v",
i, tc.Input, result.Value, tc.Result)
}
}
}
示例6: Example_functions
func Example_functions() {
input := "${lower(var.test)} - ${6 + 2}"
tree, err := hil.Parse(input)
if err != nil {
log.Fatal(err)
}
lowerCase := ast.Function{
ArgTypes: []ast.Type{ast.TypeString},
ReturnType: ast.TypeString,
Variadic: false,
Callback: func(inputs []interface{}) (interface{}, error) {
input := inputs[0].(string)
return strings.ToLower(input), nil
},
}
config := &hil.EvalConfig{
GlobalScope: &ast.BasicScope{
VarMap: map[string]ast.Variable{
"var.test": ast.Variable{
Type: ast.TypeString,
Value: "TEST STRING",
},
},
FuncMap: map[string]ast.Function{
"lower": lowerCase,
},
},
}
result, err := hil.Eval(tree, config)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Type: %s\n", result.Type)
fmt.Printf("Value: %s\n", result.Value)
// Output:
// Type: TypeString
// Value: test string - 8
}
示例7: Example_basic
func Example_basic() {
input := "${6 + 2}"
tree, err := hil.Parse(input)
if err != nil {
log.Fatal(err)
}
value, valueType, err := hil.Eval(tree, &hil.EvalConfig{})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Type: %s\n", valueType)
fmt.Printf("Value: %s\n", value)
// Output:
// Type: TypeString
// Value: 8
}
示例8: TestInterpolateFuncTimestamp
func TestInterpolateFuncTimestamp(t *testing.T) {
currentTime := time.Now().UTC()
ast, err := hil.Parse("${timestamp()}")
if err != nil {
t.Fatalf("err: %s", err)
}
result, err := hil.Eval(ast, langEvalConfig(nil))
if err != nil {
t.Fatalf("err: %s", err)
}
resultTime, err := time.Parse(time.RFC3339, result.Value.(string))
if err != nil {
t.Fatalf("Error parsing timestamp: %s", err)
}
if resultTime.Sub(currentTime).Seconds() > 10.0 {
t.Fatalf("Timestamp Diff too large. Expected: %s\nRecieved: %s", currentTime.Format(time.RFC3339), result.Value.(string))
}
}
示例9: TestInterpolateFuncUUID
func TestInterpolateFuncUUID(t *testing.T) {
results := make(map[string]bool)
for i := 0; i < 100; i++ {
ast, err := hil.Parse("${uuid()}")
if err != nil {
t.Fatalf("err: %s", err)
}
result, err := hil.Eval(ast, langEvalConfig(nil))
if err != nil {
t.Fatalf("err: %s", err)
}
if results[result.Value.(string)] {
t.Fatalf("Got unexpected duplicate uuid: %s", result.Value)
}
results[result.Value.(string)] = true
}
}
示例10: DetectUserVariables
// DetectUserVariables parses the template for any ${var.foo}, ${var.bar},
// etc.. user variables. It returns a list of found variables with, example:
// []string{"foo", "bar"}. The returned list only contains unique names, so any
// user variable which declared multiple times is neglected, only the last
// occurence is being added.
func (t *Template) DetectUserVariables(prefix string) (map[string]string, error) {
if !strings.HasSuffix(prefix, "_") {
prefix = prefix + "_"
}
out, err := t.JsonOutput()
if err != nil {
return nil, err
}
// get AST first, it's capable of parsing json
a, err := hil.Parse(out)
if err != nil {
return nil, err
}
// read the variables from the given AST. This is basically just iterating
// over the AST node and does the heavy lifting for us
vars, err := config.DetectVariables(a)
if err != nil {
return nil, err
}
// filter out duplicates
userVars := make(map[string]string, 0)
for _, v := range vars {
// be sure we only get userVariables, as there is many ways of
// declaring variables
u, ok := v.(*config.UserVariable)
if !ok {
continue
}
if _, ok = userVars[u.Name]; !ok && strings.HasPrefix(u.Name, prefix) {
userVars[u.Name] = ""
}
}
return userVars, nil
}
示例11: execute
// execute parses and executes a template using vars.
func execute(s string, vars map[string]interface{}) (string, error) {
root, err := hil.Parse(s)
if err != nil {
return "", err
}
varmap := make(map[string]ast.Variable)
for k, v := range vars {
// As far as I can tell, v is always a string.
// If it's not, tell the user gracefully.
s, ok := v.(string)
if !ok {
return "", fmt.Errorf("unexpected type for variable %q: %T", k, v)
}
varmap[k] = ast.Variable{
Value: s,
Type: ast.TypeString,
}
}
cfg := hil.EvalConfig{
GlobalScope: &ast.BasicScope{
VarMap: varmap,
FuncMap: config.Funcs(),
},
}
result, err := hil.Eval(root, &cfg)
if err != nil {
return "", err
}
if result.Type != hil.TypeString {
return "", fmt.Errorf("unexpected output hil.Type: %v", result.Type)
}
return result.Value.(string), nil
}
示例12: Eval
func Eval(tmpl string, variables Variables) (string, error) {
tree, err := hil.Parse(tmpl)
if err != nil {
return "", err
}
varMap := make(map[string]ast.Variable)
for n, v := range variables {
varMap[n] = ast.Variable{Type: ast.TypeString, Value: v}
}
config := &hil.EvalConfig{
GlobalScope: &ast.BasicScope{VarMap: varMap},
}
out, _, err := hil.Eval(tree, config)
if err != nil {
return "", err
}
if s, ok := out.(string); ok {
return s, nil
} else {
return "", fmt.Errorf("This is a bug: expected to find string, but found %s.\nPlease report that to %s", reflect.TypeOf(out), bugTracker)
}
}
示例13: Primitive
func (w *interpolationWalker) Primitive(v reflect.Value) error {
setV := v
// We only care about strings
if v.Kind() == reflect.Interface {
setV = v
v = v.Elem()
}
if v.Kind() != reflect.String {
return nil
}
astRoot, err := hil.Parse(v.String())
if err != nil {
return err
}
// If the AST we got is just a literal string value with the same
// value then we ignore it. We have to check if its the same value
// because it is possible to input a string, get out a string, and
// have it be different. For example: "foo-$${bar}" turns into
// "foo-${bar}"
if n, ok := astRoot.(*ast.LiteralNode); ok {
if s, ok := n.Value.(string); ok && s == v.String() {
return nil
}
}
if w.ContextF != nil {
w.ContextF(w.loc, astRoot)
}
if w.F == nil {
return nil
}
replaceVal, err := w.F(astRoot)
if err != nil {
return fmt.Errorf(
"%s in:\n\n%s",
err, v.String())
}
if w.Replace {
// We need to determine if we need to remove this element
// if the result contains any "UnknownVariableValue" which is
// set if it is computed. This behavior is different if we're
// splitting (in a SliceElem) or not.
remove := false
if w.loc == reflectwalk.SliceElem {
switch typedReplaceVal := replaceVal.(type) {
case string:
if typedReplaceVal == UnknownVariableValue {
remove = true
}
case []interface{}:
if hasUnknownValue(typedReplaceVal) {
remove = true
}
}
} else if replaceVal == UnknownVariableValue {
remove = true
}
if remove {
w.unknownKeys = append(w.unknownKeys, strings.Join(w.key, "."))
}
resultVal := reflect.ValueOf(replaceVal)
switch w.loc {
case reflectwalk.MapKey:
m := w.cs[len(w.cs)-1]
// Delete the old value
var zero reflect.Value
m.SetMapIndex(w.csData.(reflect.Value), zero)
// Set the new key with the existing value
m.SetMapIndex(resultVal, w.lastValue)
// Set the key to be the new key
w.csData = resultVal
case reflectwalk.MapValue:
// If we're in a map, then the only way to set a map value is
// to set it directly.
m := w.cs[len(w.cs)-1]
mk := w.csData.(reflect.Value)
m.SetMapIndex(mk, resultVal)
default:
// Otherwise, we should be addressable
setV.Set(resultVal)
}
}
return nil
}