123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- package parser
- import (
- "bytes"
- "fmt"
- "reflect"
- "strconv"
- )
- // ParserCommaSeparatedValues parses the comma separated values
- // and returns a map of key-value pairs
- // examples:
- // data: a=1,b=2
- //
- // T: type struct {
- // A int `comma:"a"`
- // B string `comma:"b"`
- // }
- //
- // return:
- // T{A: 1, B: "2"}
- func ParserCommaSeparatedValues[T any](data []byte) (T, error) {
- var result T
- if len(data) == 0 {
- return result, nil
- }
- // Split by comma
- pairs := bytes.Split(data, []byte(","))
- // Create map to store key-value pairs
- values := make(map[string]string)
- // Parse each key-value pair
- for _, pair := range pairs {
- kv := bytes.Split(pair, []byte("="))
- if len(kv) != 2 {
- return result, fmt.Errorf("invalid key-value pair: %s", pair)
- }
- key := string(bytes.TrimSpace(kv[0]))
- value := string(bytes.TrimSpace(kv[1]))
- values[key] = value
- }
- // Convert map to struct using reflection
- resultValue := reflect.ValueOf(&result).Elem()
- resultType := resultValue.Type()
- for i := 0; i < resultType.NumField(); i++ {
- field := resultType.Field(i)
- fieldValue := resultValue.Field(i)
- // Get comma tag value
- tag := field.Tag.Get("comma")
- if tag == "" {
- tag = field.Name
- }
- if value, ok := values[tag]; ok {
- switch field.Type.Kind() {
- case reflect.String:
- fieldValue.SetString(value)
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- if intVal, err := strconv.ParseInt(value, 10, 64); err == nil {
- fieldValue.SetInt(intVal)
- }
- case reflect.Float32, reflect.Float64:
- if floatVal, err := strconv.ParseFloat(value, 64); err == nil {
- fieldValue.SetFloat(floatVal)
- }
- case reflect.Bool:
- if boolVal, err := strconv.ParseBool(value); err == nil {
- fieldValue.SetBool(boolVal)
- }
- }
- }
- }
- return result, nil
- }
|