github.com/safedep/dry@v0.0.0-20241016050132-a15651f0548b/config/encoder.go (about) 1 package config 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "reflect" 7 "strconv" 8 ) 9 10 // JSON based config type encoder 11 type JSONConfigEncoder[T any] struct{} 12 13 func (j *JSONConfigEncoder[T]) Encode(v T) (string, error) { 14 data, err := json.Marshal(v) 15 if err != nil { 16 return "", err 17 } 18 19 return string(data), nil 20 } 21 22 func (j *JSONConfigEncoder[T]) Decode(s string) (T, error) { 23 var v T 24 25 err := json.Unmarshal([]byte(s), &v) 26 if err != nil { 27 return v, err 28 } 29 30 return v, nil 31 } 32 33 // Go strconv based config type encoder. It only supports 34 // decoding and do not support encoding 35 type strconvConfigEncoder[T any] struct{} 36 37 func (s *strconvConfigEncoder[T]) Decode(v string) (T, error) { 38 var value T 39 40 vt := reflect.TypeOf(value).Kind() 41 switch vt { 42 case reflect.String: 43 value = reflect.ValueOf(v).Interface().(T) 44 case reflect.Int, reflect.Int64: 45 p, err := strconv.ParseInt(v, 10, 64) 46 if err != nil { 47 value = reflect.ValueOf(p).Interface().(T) 48 } else { 49 return value, err 50 } 51 case reflect.Float64: 52 p, err := strconv.ParseFloat(v, 64) 53 if err != nil { 54 value = reflect.ValueOf(p).Interface().(T) 55 } else { 56 return value, err 57 } 58 default: 59 return value, fmt.Errorf("strconvConfigEncoder does not support decoding %v", vt) 60 } 61 62 return value, nil 63 } 64 65 func (s *strconvConfigEncoder[T]) Encode(v T) (string, error) { 66 return "", fmt.Errorf("strconvConfigEncoder does not support encoding") 67 } 68 69 // NewStrconvConfigEncoder returns a new instance of strconvConfigEncoder 70 // which is suitable only for decoding strings into Go types based on 71 // the type of the value obtained through reflection 72 func NewStrconvConfigEncoder[T any]() ConfigEncoder[T] { 73 return &strconvConfigEncoder[T]{} 74 }