go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/configutil/env.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package configutil 9 10 import ( 11 "context" 12 "fmt" 13 "strconv" 14 "time" 15 ) 16 17 // Env returns an environment variable with a given key as a value source. 18 func Env[T any](key string) func(context.Context) (*T, error) { 19 return func(ctx context.Context) (*T, error) { 20 output := new(T) 21 raw, ok := GetEnvVars(ctx)[key] 22 if !ok { 23 return nil, nil 24 } 25 if err := parseGeneric(output, raw); err != nil { 26 return nil, err 27 } 28 return output, nil 29 } 30 } 31 32 func parseGeneric(ref any, raw string) error { 33 switch refv := ref.(type) { 34 case *string: 35 *refv = raw 36 return nil 37 case *[]byte: 38 *refv = []byte(raw) 39 return nil 40 case *float64: 41 parsed, err := strconv.ParseFloat(raw, 64) 42 if err != nil { 43 return err 44 } 45 *refv = parsed 46 return nil 47 case *float32: 48 parsed, err := strconv.ParseFloat(raw, 32) 49 if err != nil { 50 return err 51 } 52 *refv = float32(parsed) 53 return nil 54 case *int: 55 parsed, err := strconv.Atoi(raw) 56 if err != nil { 57 return err 58 } 59 *refv = parsed 60 return nil 61 case *int16: 62 parsed, err := strconv.ParseInt(raw, 10, 16) 63 if err != nil { 64 return err 65 } 66 *refv = int16(parsed) 67 return nil 68 case *int32: 69 parsed, err := strconv.ParseInt(raw, 10, 32) 70 if err != nil { 71 return err 72 } 73 *refv = int32(parsed) 74 return nil 75 case *int64: 76 parsed, err := strconv.ParseInt(raw, 10, 64) 77 if err != nil { 78 return err 79 } 80 *refv = parsed 81 return nil 82 case *uint8: 83 parsed, err := strconv.ParseUint(raw, 10, 8) 84 if err != nil { 85 return err 86 } 87 *refv = uint8(parsed) 88 return nil 89 case *uint16: 90 parsed, err := strconv.ParseUint(raw, 10, 16) 91 if err != nil { 92 return err 93 } 94 *refv = uint16(parsed) 95 return nil 96 case *uint32: 97 parsed, err := strconv.ParseUint(raw, 10, 32) 98 if err != nil { 99 return err 100 } 101 *refv = uint32(parsed) 102 return nil 103 case *uint64: 104 parsed, err := strconv.ParseUint(raw, 10, 64) 105 if err != nil { 106 return err 107 } 108 *refv = parsed 109 return nil 110 case *time.Duration: 111 parsed, err := time.ParseDuration(raw) 112 if err != nil { 113 return err 114 } 115 *refv = parsed 116 return nil 117 default: 118 return fmt.Errorf("invalid parse target: %T", ref) 119 } 120 }