github.com/grpc-ecosystem/grpc-gateway/v2@v2.19.1/runtime/convert.go (about) 1 package runtime 2 3 import ( 4 "encoding/base64" 5 "fmt" 6 "strconv" 7 "strings" 8 9 "google.golang.org/protobuf/encoding/protojson" 10 "google.golang.org/protobuf/types/known/durationpb" 11 "google.golang.org/protobuf/types/known/timestamppb" 12 "google.golang.org/protobuf/types/known/wrapperspb" 13 ) 14 15 // String just returns the given string. 16 // It is just for compatibility to other types. 17 func String(val string) (string, error) { 18 return val, nil 19 } 20 21 // StringSlice converts 'val' where individual strings are separated by 22 // 'sep' into a string slice. 23 func StringSlice(val, sep string) ([]string, error) { 24 return strings.Split(val, sep), nil 25 } 26 27 // Bool converts the given string representation of a boolean value into bool. 28 func Bool(val string) (bool, error) { 29 return strconv.ParseBool(val) 30 } 31 32 // BoolSlice converts 'val' where individual booleans are separated by 33 // 'sep' into a bool slice. 34 func BoolSlice(val, sep string) ([]bool, error) { 35 s := strings.Split(val, sep) 36 values := make([]bool, len(s)) 37 for i, v := range s { 38 value, err := Bool(v) 39 if err != nil { 40 return nil, err 41 } 42 values[i] = value 43 } 44 return values, nil 45 } 46 47 // Float64 converts the given string representation into representation of a floating point number into float64. 48 func Float64(val string) (float64, error) { 49 return strconv.ParseFloat(val, 64) 50 } 51 52 // Float64Slice converts 'val' where individual floating point numbers are separated by 53 // 'sep' into a float64 slice. 54 func Float64Slice(val, sep string) ([]float64, error) { 55 s := strings.Split(val, sep) 56 values := make([]float64, len(s)) 57 for i, v := range s { 58 value, err := Float64(v) 59 if err != nil { 60 return nil, err 61 } 62 values[i] = value 63 } 64 return values, nil 65 } 66 67 // Float32 converts the given string representation of a floating point number into float32. 68 func Float32(val string) (float32, error) { 69 f, err := strconv.ParseFloat(val, 32) 70 if err != nil { 71 return 0, err 72 } 73 return float32(f), nil 74 } 75 76 // Float32Slice converts 'val' where individual floating point numbers are separated by 77 // 'sep' into a float32 slice. 78 func Float32Slice(val, sep string) ([]float32, error) { 79 s := strings.Split(val, sep) 80 values := make([]float32, len(s)) 81 for i, v := range s { 82 value, err := Float32(v) 83 if err != nil { 84 return nil, err 85 } 86 values[i] = value 87 } 88 return values, nil 89 } 90 91 // Int64 converts the given string representation of an integer into int64. 92 func Int64(val string) (int64, error) { 93 return strconv.ParseInt(val, 0, 64) 94 } 95 96 // Int64Slice converts 'val' where individual integers are separated by 97 // 'sep' into a int64 slice. 98 func Int64Slice(val, sep string) ([]int64, error) { 99 s := strings.Split(val, sep) 100 values := make([]int64, len(s)) 101 for i, v := range s { 102 value, err := Int64(v) 103 if err != nil { 104 return nil, err 105 } 106 values[i] = value 107 } 108 return values, nil 109 } 110 111 // Int32 converts the given string representation of an integer into int32. 112 func Int32(val string) (int32, error) { 113 i, err := strconv.ParseInt(val, 0, 32) 114 if err != nil { 115 return 0, err 116 } 117 return int32(i), nil 118 } 119 120 // Int32Slice converts 'val' where individual integers are separated by 121 // 'sep' into a int32 slice. 122 func Int32Slice(val, sep string) ([]int32, error) { 123 s := strings.Split(val, sep) 124 values := make([]int32, len(s)) 125 for i, v := range s { 126 value, err := Int32(v) 127 if err != nil { 128 return nil, err 129 } 130 values[i] = value 131 } 132 return values, nil 133 } 134 135 // Uint64 converts the given string representation of an integer into uint64. 136 func Uint64(val string) (uint64, error) { 137 return strconv.ParseUint(val, 0, 64) 138 } 139 140 // Uint64Slice converts 'val' where individual integers are separated by 141 // 'sep' into a uint64 slice. 142 func Uint64Slice(val, sep string) ([]uint64, error) { 143 s := strings.Split(val, sep) 144 values := make([]uint64, len(s)) 145 for i, v := range s { 146 value, err := Uint64(v) 147 if err != nil { 148 return nil, err 149 } 150 values[i] = value 151 } 152 return values, nil 153 } 154 155 // Uint32 converts the given string representation of an integer into uint32. 156 func Uint32(val string) (uint32, error) { 157 i, err := strconv.ParseUint(val, 0, 32) 158 if err != nil { 159 return 0, err 160 } 161 return uint32(i), nil 162 } 163 164 // Uint32Slice converts 'val' where individual integers are separated by 165 // 'sep' into a uint32 slice. 166 func Uint32Slice(val, sep string) ([]uint32, error) { 167 s := strings.Split(val, sep) 168 values := make([]uint32, len(s)) 169 for i, v := range s { 170 value, err := Uint32(v) 171 if err != nil { 172 return nil, err 173 } 174 values[i] = value 175 } 176 return values, nil 177 } 178 179 // Bytes converts the given string representation of a byte sequence into a slice of bytes 180 // A bytes sequence is encoded in URL-safe base64 without padding 181 func Bytes(val string) ([]byte, error) { 182 b, err := base64.StdEncoding.DecodeString(val) 183 if err != nil { 184 b, err = base64.URLEncoding.DecodeString(val) 185 if err != nil { 186 return nil, err 187 } 188 } 189 return b, nil 190 } 191 192 // BytesSlice converts 'val' where individual bytes sequences, encoded in URL-safe 193 // base64 without padding, are separated by 'sep' into a slice of bytes slices slice. 194 func BytesSlice(val, sep string) ([][]byte, error) { 195 s := strings.Split(val, sep) 196 values := make([][]byte, len(s)) 197 for i, v := range s { 198 value, err := Bytes(v) 199 if err != nil { 200 return nil, err 201 } 202 values[i] = value 203 } 204 return values, nil 205 } 206 207 // Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp. 208 func Timestamp(val string) (*timestamppb.Timestamp, error) { 209 var r timestamppb.Timestamp 210 val = strconv.Quote(strings.Trim(val, `"`)) 211 unmarshaler := &protojson.UnmarshalOptions{} 212 if err := unmarshaler.Unmarshal([]byte(val), &r); err != nil { 213 return nil, err 214 } 215 return &r, nil 216 } 217 218 // Duration converts the given string into a timestamp.Duration. 219 func Duration(val string) (*durationpb.Duration, error) { 220 var r durationpb.Duration 221 val = strconv.Quote(strings.Trim(val, `"`)) 222 unmarshaler := &protojson.UnmarshalOptions{} 223 if err := unmarshaler.Unmarshal([]byte(val), &r); err != nil { 224 return nil, err 225 } 226 return &r, nil 227 } 228 229 // Enum converts the given string into an int32 that should be type casted into the 230 // correct enum proto type. 231 func Enum(val string, enumValMap map[string]int32) (int32, error) { 232 e, ok := enumValMap[val] 233 if ok { 234 return e, nil 235 } 236 237 i, err := Int32(val) 238 if err != nil { 239 return 0, fmt.Errorf("%s is not valid", val) 240 } 241 for _, v := range enumValMap { 242 if v == i { 243 return i, nil 244 } 245 } 246 return 0, fmt.Errorf("%s is not valid", val) 247 } 248 249 // EnumSlice converts 'val' where individual enums are separated by 'sep' 250 // into a int32 slice. Each individual int32 should be type casted into the 251 // correct enum proto type. 252 func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) { 253 s := strings.Split(val, sep) 254 values := make([]int32, len(s)) 255 for i, v := range s { 256 value, err := Enum(v, enumValMap) 257 if err != nil { 258 return nil, err 259 } 260 values[i] = value 261 } 262 return values, nil 263 } 264 265 // Support for google.protobuf.wrappers on top of primitive types 266 267 // StringValue well-known type support as wrapper around string type 268 func StringValue(val string) (*wrapperspb.StringValue, error) { 269 return wrapperspb.String(val), nil 270 } 271 272 // FloatValue well-known type support as wrapper around float32 type 273 func FloatValue(val string) (*wrapperspb.FloatValue, error) { 274 parsedVal, err := Float32(val) 275 return wrapperspb.Float(parsedVal), err 276 } 277 278 // DoubleValue well-known type support as wrapper around float64 type 279 func DoubleValue(val string) (*wrapperspb.DoubleValue, error) { 280 parsedVal, err := Float64(val) 281 return wrapperspb.Double(parsedVal), err 282 } 283 284 // BoolValue well-known type support as wrapper around bool type 285 func BoolValue(val string) (*wrapperspb.BoolValue, error) { 286 parsedVal, err := Bool(val) 287 return wrapperspb.Bool(parsedVal), err 288 } 289 290 // Int32Value well-known type support as wrapper around int32 type 291 func Int32Value(val string) (*wrapperspb.Int32Value, error) { 292 parsedVal, err := Int32(val) 293 return wrapperspb.Int32(parsedVal), err 294 } 295 296 // UInt32Value well-known type support as wrapper around uint32 type 297 func UInt32Value(val string) (*wrapperspb.UInt32Value, error) { 298 parsedVal, err := Uint32(val) 299 return wrapperspb.UInt32(parsedVal), err 300 } 301 302 // Int64Value well-known type support as wrapper around int64 type 303 func Int64Value(val string) (*wrapperspb.Int64Value, error) { 304 parsedVal, err := Int64(val) 305 return wrapperspb.Int64(parsedVal), err 306 } 307 308 // UInt64Value well-known type support as wrapper around uint64 type 309 func UInt64Value(val string) (*wrapperspb.UInt64Value, error) { 310 parsedVal, err := Uint64(val) 311 return wrapperspb.UInt64(parsedVal), err 312 } 313 314 // BytesValue well-known type support as wrapper around bytes[] type 315 func BytesValue(val string) (*wrapperspb.BytesValue, error) { 316 parsedVal, err := Bytes(val) 317 return wrapperspb.Bytes(parsedVal), err 318 }