jeudi 21 septembre 2023

Map values from one struct to another struct by reflection

I am building simple system where KV struct represents Key, Value Pair of Property name and Value.

Model stuct has various simple types of Properties.

type Model struct {
    Id                         string    
    StringType                 *string
    BoolType                   *bool
    TimeType                   *time.Time
    FloatType                  *float64
    IntType                    *int
}

type KV struct {
    Fieldname       *string
    Oldvalue        *string
}

KV Struct parsing will contain following data

IntType 5
IntType nil
TimeType 2023-01-01
Id 4
BoolType nil
StringType test

Essentially need to build history of Model Object with whatever the property KV pair data available.

currentRow := Model{} //it can contain some values or empty struct or nil values
for j, a := range sysIdAudit {
    fact := currentRow
    la := a

    //reflect on fact
    ref := reflect.Indirect(reflect.ValueOf(&fact))
    fv := ref.FieldByName(strcase.ToCamel(*la.Fieldname))

    if !fv.IsValid() {
        continue
    }

    //v := reflect.ValueOf(a.Oldvalue)
    if la.Oldvalue == nil {
        fv.Set(reflect.Zero(fv.Type()))
    } else {

        switch fv.Elem().Type().Name() {
        case "int64":
            i, _ := strconv.ParseInt(*la.Oldvalue, 10, 64)
            reflect.Indirect(fv).SetInt(i)
            break
        case "float64":
            f, _ := strconv.ParseFloat(*la.Oldvalue, 8)
            reflect.Indirect(fv).SetFloat(f)
            break
        case "string":
            reflect.Indirect(fv).SetString(*la.Oldvalue)
            break
        case "bool":
            b, _ := strconv.ParseBool(*la.Oldvalue)
            reflect.Indirect(fv).SetBool(b)
            break
        case "Time":
            t, _ := time.Parse("2006-01-02 15:04", *la.Oldvalue)
            reflect.Indirect(fv).Set(reflect.ValueOf(t))
            break
        default:
            fv.Set(fv)
            break
        }

    }

    history = append(history, fact)
    currentRow = fact
}

I am running into multiple panics (basically strugulling to understand reflection properly and use it)

panic: reflect: call of reflect.Value.Type on zero Value -> on this line switch fv.Elem().Type().Name()





Aucun commentaire:

Enregistrer un commentaire