1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
| package util
import ( "fmt" "strconv" "strings" "time"
"github.com/google/uuid" "github.com/pkg/errors" )
func (m ValueMap) ParseBool(path string, allowMissing bool, allowEmpty bool) (bool, error) { result, err := m.GetPath(path, allowMissing) if err != nil { return false, errors.Wrap(err, "invalid bool") } switch t := result.(type) { case bool: return t, nil case string: return t == BoolTrue, nil case nil: if !allowEmpty { return false, errors.Errorf("could not find bool for path [%s]", path) } return false, nil default: return false, invalidTypeError(path, "bool", t) } }
func (m ValueMap) ParseFloat(path string, allowMissing bool, allowEmpty bool) (float64, error) { result, err := m.GetPath(path, allowMissing) if err != nil { return 0, errors.Wrap(err, "invalid float") } switch t := result.(type) { case int: return float64(t), nil case int64: return float64(t), nil case float64: return t, nil case string: return strconv.ParseFloat(t, 64) case nil: if !allowEmpty { return 0, errors.Errorf("could not find float for path [%s]", path) } return 0, nil default: return 0, invalidTypeError(path, "float", t) } }
func (m ValueMap) ParseInt(path string, allowMissing bool, allowEmpty bool) (int, error) { result, err := m.GetPath(path, allowMissing) if err != nil { return 0, errors.Wrap(err, "invalid int") } return valueInt(path, result, allowEmpty) }
func valueInt(path string, r any, allowEmpty bool) (int, error) { switch t := r.(type) { case int: return t, nil case int64: return int(t), nil case float64: return int(t), nil case string: ret, err := strconv.ParseInt(t, 10, 32) return int(ret), err case nil: if !allowEmpty { return 0, errors.Errorf("could not find int for path [%s]", path) } return 0, nil default: return 0, invalidTypeError(path, "int", t) } }
func (m ValueMap) ParseString(path string, allowMissing bool, allowEmpty bool) (string, error) { result, err := m.GetPath(path, allowMissing) if err != nil { return "", errors.Wrap(err, "invalid string") } switch t := result.(type) { case string: if (!allowEmpty) && t == "" { return "", errors.New("empty string") } return t, nil case []string: if (!allowEmpty) && len(t) == 0 || t[0] == "" { return "", errors.New("empty string") } return strings.Join(t, "||"), nil case nil: if !allowEmpty { return "", errors.Errorf("could not find string for path [%s]", path) } return "", nil default: return fmt.Sprint(t), nil } }
func (m ValueMap) ParseTime(path string, allowMissing bool, allowEmpty bool) (*time.Time, error) { result, err := m.GetPath(path, allowMissing) if err != nil { return nil, errors.Wrap(err, "invalid time") } switch t := result.(type) { case time.Time: return &t, nil case *time.Time: if t == nil && (!allowEmpty) { return nil, errors.New("empty time") } return t, nil case string: ret, err := TimeFromString(t) if err != nil { return nil, decorateError(m, path, "time", err) } if ret == nil && (!allowEmpty) { return nil, errors.Errorf("invalid time [%s]", t) } return ret, nil case nil: if !allowEmpty { return nil, errors.Errorf("could not find time for path [%s]", path) } return nil, nil default: return nil, invalidTypeError(path, "time", t) } }
func (m ValueMap) ParseUUID(path string, allowMissing bool, allowEmpty bool) (*uuid.UUID, error) { result, err := m.GetPath(path, allowMissing) if err != nil { return nil, errors.Wrap(err, "invalid uuid") }
switch t := result.(type) { case *uuid.UUID: if t == nil && (!allowEmpty) { return nil, errors.New("empty uuid") } return t, nil case uuid.UUID: if t == uuid.Nil && (!allowEmpty) { return nil, errors.New("empty uuid") } return &t, nil case string: if t == "" && allowEmpty { return nil, nil } ret, err := uuid.Parse(t) if err != nil { return nil, err } if ret == uuid.Nil && (!allowEmpty) { return nil, errors.Errorf("could not find uuid for path [%s]", path) } return &ret, nil case nil: if !allowEmpty { return nil, errors.Errorf("could not find uuid for path [%s]", path) } return nil, nil default: return nil, invalidTypeError(path, "uuid", t) } }
func decorateError(m ValueMap, path string, t string, err error) error { if err == nil { return nil } return errors.Wrapf(err, "error parsing [%s] as [%s] from map with fields [%s]", path, t, strings.Join(m.Keys(), ", ")) }
func invalidTypeError(path string, t string, observed any) error { return errors.Errorf("unable to parse [%s] at path [%s], invalid type [%T]", t, path, observed) }
|