vendredi 7 septembre 2018

Go using reflection on time fields in custom UnmarshallJson func

I am trying to use reflection to take the time fields from a struct and through a custom UnmarshallJSON func, see which ones come across as the time.IsZero value and which ones dont. They are coming across as *time.Time and I dont want to use omitempty (as I cant, and need the field to be cleared and persisted as such). Right now I am checking each field individually, but I was wondering if there was a way to do it through reflection to make it more robust, if another time field was added, I didnt need to add the corresponding check for it.

Right now this is how im doing it:

type A struct {
    X *time.Time `json:"x"`
    Y *time.Time `json:"y"`

}

func (a *A) UnmarshalJSON(b []byte) (err error) {
    type Alias A
    s := &struct {
      X time.Time `json:"x"`
      Y time.Time `json:"y"`
}{
        Alias: (*Alias)(a),
    }
    if err := json.Unmarshal(b, &s); err != nil {
        return err
    }

if s.X.IsZero() {
        a.X = nil
    } else {
        a.X = &s.X
    }

if s.Y.IsZero() {
        a.Y = nil
    } else {
        a.Y = &s.Y
    }

I would rather not have to check each time field and instead do something like this

values := reflect.ValueOf(&s).Elem()

for i := 0; i < values.NumField(); i++ {
    fieldName := values.Type().Field(i).Name
    fieldValue := values.Field(i).Interface()
    if fieldValue == nil {
        a.fieldName = nil
    } else {
      a.fieldName = &s.fieldName
    }

The problem comes when I try to do a.fieldName or s.fieldName, am I missing something? has anyone ran into this or (hopefully) solved this problem?





Aucun commentaire:

Enregistrer un commentaire