lundi 19 octobre 2020

Mapping Go structs with inline conditional logic and pointers

Go here. I have 3 structs:

type BoolResp struct {
    Val      *bool `json:"val,omitempty"`
    MoreInfo *bool `json:"moreInfo"`
}

type Output struct {
    Id                     uuid.UUID  `json:"id" gorm:"column:id;type:uuid;primary_key;not null"`
    SignInTimestamp        *time.Time `json:"ts" gorm:"column:sign_in_timestamp;type:timestamp with time zone;"`
    KidneyInfo             *bool      `json:"kidney_info" gorm:"column:kidney_info;type:boolean;"`
}

type Input struct {
    MetricID                 uuid.UUID     `json:"metricId,omitempty"`
    Responses                struct {
      Kidney1                  BoolResp         `json:"kidney1"`
      Kidney2                  BoolResp         `json:"kidney2"`
  } `json:"responses"`
}

I have the following function, which takes an instance of an Input type and converts it to an instance of an Output:

func (mp *DataConverter) ConvertToOutput(input *Input) Output {

  ret := Output {
        Id:                       input.MetricID,
        SignInTimestamp:          now(),
  }

  return ret
  
}

This function works great. The only thing I'm missing is the conversion of the KidneyInfo field on the Output. The logic for that is as follows:

  • If the Input.Responses.Kidney1.MoreInfo is true; or
  • If the Input.Responses.Kidney2.MoreInfo is true; then set Output.KidneyInfo to true

So I've tried rewriting this function as best as I could:

func (mp *DataConverter) ConvertToOutput(input *Input) Output {

  ret := Output {
        Id:                       input.MetricID,
        SignInTimestamp:          now(),
  }

  if *input.Responses.Kidney1.MoreInfo || *input.Responses.Kidney1.MoreInfo {
    *ret.KidneyInfo = true
  }

  return ret
  
}

But I feel like thats a really ugly way of impementing it. Is there a more efficient, more readable way to write this type of conditional logic (ideally inline), especially with all the pointers involved?


With nil checks in place:

if (*input.Responses != nil && *mr.Responses.Kidney1 != nil && *mr.Responses.Kidney1.MoreInfo) ||
        (*input.Responses != nil && *mr.Responses.Kidney2 != nil && *mr.Responses.Kidney2.MoreInfo) {
    *ret.KidneyInfo = true
}

Aucun commentaire:

Enregistrer un commentaire