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  }