code: func (f *IfFunc) UnmarshalJSON(buf []byte) error {
  	v := struct {
  		FnIf [3]json.RawMessage `json:"Fn::If"`
  	}{}
  	if err := json.Unmarshal(buf, &v); err != nil {
  		return err
  	}
  	if err := json.Unmarshal(v.FnIf[0], &f.Condition); err != nil {
  		return err
  	}
  
  	var probeValue interface{}
  	if err := json.Unmarshal(v.FnIf[1], &probeValue); err != nil {
  		return err
  	}
  
  	switch reflect.ValueOf(probeValue).Kind() {
  	case reflect.Array:
  		f.list = true
  	case reflect.String:
  		f.list = false
  	case reflect.Map:
  		expr, err := unmarshalFunc(v.FnIf[1])
  		if err == nil {
  			if _, ok := expr.(StringListFunc); ok {
  				f.list = true
  			}
  		}
  	}
  
  	if f.list {
  		f.ValueIfTrue = StringListExpr{}
  		f.ValueIfFalse = StringListExpr{}
  	} else {
  		f.ValueIfTrue = StringExpr{}
  		f.ValueIfFalse = StringExpr{}
  	}
  
  	if err := json.Unmarshal(v.FnIf[1], &f.ValueIfTrue); err != nil {
  		return err
  	}
  
  	if err := json.Unmarshal(v.FnIf[2], &f.ValueIfFalse); err != nil {
  		return err
  	}
  	return nil
  }
docs: // UnmarshalJSON sets the object from the provided JSON representation