Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
124 lines
3.4 KiB
Go
124 lines
3.4 KiB
Go
// Copyright IBM Corp. 2021, 2026
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package values
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"google.golang.org/protobuf/types/known/structpb"
|
|
)
|
|
|
|
// GetStringValue returns a string value and no error if the given key
|
|
// is found in the provided proto struct input. An error is returned
|
|
// if the key is not found or the value type is not a string. An error is
|
|
// returned if the parameter argument "required" is set to true
|
|
// and the value from the proto struct input is empty.
|
|
func GetStringValue(in *structpb.Struct, k string, required bool) (string, error) {
|
|
mv := in.GetFields()
|
|
v, ok := mv[k]
|
|
if !ok {
|
|
if required {
|
|
return "", fmt.Errorf("missing required value %q", k)
|
|
}
|
|
|
|
return "", nil
|
|
}
|
|
|
|
s, ok := v.AsInterface().(string)
|
|
if !ok {
|
|
return "", fmt.Errorf("unexpected type for value %q: want string, got %T", k, v.AsInterface())
|
|
}
|
|
|
|
if s == "" && required {
|
|
return "", fmt.Errorf("value %q cannot be empty", k)
|
|
}
|
|
|
|
return s, nil
|
|
}
|
|
|
|
// GetBoolValue returns a boolean value and no error if the given key
|
|
// is found in the provided proto struct input. An error is returned
|
|
// if the key is not found or the value type is not a bool.
|
|
func GetBoolValue(in *structpb.Struct, k string, required bool) (bool, error) {
|
|
mv := in.GetFields()
|
|
v, ok := mv[k]
|
|
if !ok {
|
|
if required {
|
|
return false, fmt.Errorf("missing required value %q", k)
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
b, ok := v.AsInterface().(bool)
|
|
if !ok {
|
|
return false, fmt.Errorf("unexpected type for value %q: want bool, got %T", k, v.AsInterface())
|
|
}
|
|
|
|
return b, nil
|
|
}
|
|
|
|
// GetTimeValue returns a time.Time value and no error if the given key
|
|
// is found in the provided proto struct input. An error is returned
|
|
// if the key is not found or the value type is not a parsable. The
|
|
// expected time layout is RFC3339Nano.
|
|
func GetTimeValue(in *structpb.Struct, k string) (time.Time, error) {
|
|
mv := in.GetFields()
|
|
v, ok := mv[k]
|
|
if !ok {
|
|
return time.Time{}, nil
|
|
}
|
|
|
|
tRaw, ok := v.AsInterface().(string)
|
|
if !ok {
|
|
return time.Time{}, fmt.Errorf("unexpected type for value %q: want string, got %T", k, v.AsInterface())
|
|
}
|
|
|
|
t, err := time.Parse(time.RFC3339Nano, tRaw)
|
|
if err != nil {
|
|
return time.Time{}, fmt.Errorf("could not parse time in value %q: %w", k, err)
|
|
}
|
|
|
|
return t, nil
|
|
}
|
|
|
|
// GetMapStringString returns a map[string]string value and no error if the given key
|
|
// is found in the provided proto struct input. An error is returned if the key
|
|
// is not found or the value type is not map[string]string.
|
|
func GetMapStringString(in *structpb.Struct, k string, required bool) (map[string]string, error) {
|
|
mv := in.GetFields()
|
|
v, ok := mv[k]
|
|
if !ok {
|
|
if required {
|
|
return nil, fmt.Errorf("missing required value %q", k)
|
|
}
|
|
return nil, nil
|
|
}
|
|
result := map[string]string{}
|
|
m, ok := v.AsInterface().(map[string]any)
|
|
if !ok {
|
|
return nil, fmt.Errorf("unexpected type for value %q: want map[string]string, got %T", k, v.AsInterface())
|
|
}
|
|
for mapKey, mapValue := range m {
|
|
e, ok := mapValue.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("unexpected type for value in map[%q]: want string, got %T", mapKey, mapValue)
|
|
}
|
|
result[mapKey] = e
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// StructFields returns a map[string]struct{} of the
|
|
// proto struct input.
|
|
func StructFields(s *structpb.Struct) map[string]struct{} {
|
|
m := make(map[string]struct{}, len(s.GetFields()))
|
|
for k := range s.GetFields() {
|
|
m[k] = struct{}{}
|
|
}
|
|
|
|
return m
|
|
}
|