package responseMapper import ( "context" "fmt" "reflect" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func ToModel(_ context.Context, resp interface{}, model any) error { modelValue := reflect.ValueOf(model) if modelValue.Kind() != reflect.Ptr || modelValue.IsNil() { return fmt.Errorf("model must be a pointer and must not be nil") } responseValue := reflect.ValueOf(resp) if responseValue.Kind() == reflect.Ptr { return fmt.Errorf("response must NOT be a pointer") } responseType := reflect.TypeOf(resp) modelType := reflect.TypeOf(model).Elem() mdl := modelValue.Elem() for i := 0; i < modelType.NumField(); i++ { f := modelType.Field(i) if field, ok := responseType.FieldByName(f.Name); ok { nameField := mdl.FieldByName(f.Name) switch f.Type { case reflect.TypeOf(basetypes.StringValue{}): var s *string if nameField.IsValid() && nameField.CanSet() && (field.Type == reflect.TypeOf(s) || field.Type.Kind() == reflect.TypeOf(s).Kind()) { nameField.Set( reflect.ValueOf( types.StringValue( responseValue.FieldByName(f.Name).Elem().String()))) } else { fmt.Printf("[ERR] field types differ: %s vs %s\n", field.Type, reflect.TypeOf(s)) } case reflect.TypeOf(basetypes.BoolValue{}): var s *bool if nameField.IsValid() && nameField.CanSet() && (field.Type == reflect.TypeOf(s) || field.Type.Kind() == reflect.TypeOf(s).Kind()) { if !responseValue.FieldByName(f.Name).IsZero() { nameField.Set( reflect.ValueOf( types.BoolValue( responseValue.FieldByName(f.Name).Elem().Bool(), ), ), ) } else { nameField.Set( reflect.ValueOf( types.BoolValue( false, ), ), ) } } else { fmt.Printf("[ERR] field types differ: %s vs %s\n", field.Type, reflect.TypeOf(s)) } case reflect.TypeOf(basetypes.Int32Value{}): case reflect.TypeOf(basetypes.Int64Value{}): var i32 *int32 var i64 *int64 if nameField.IsValid() && nameField.CanSet() && (field.Type.Kind() == reflect.TypeOf(i32).Kind() || field.Type.Kind() == reflect.TypeOf(i64).Kind()) { if !responseValue.FieldByName(f.Name).IsZero() { nameField.Set( reflect.ValueOf( types.Int64Value( responseValue.FieldByName(f.Name).Elem().Int(), ), ), ) } else { nameField.Set( reflect.ValueOf( types.Int64Value( 0, ), ), ) } } else { fmt.Printf("[ERR] field types differ: %s vs %s or %s\n", field.Type, reflect.TypeOf(i32), reflect.TypeOf(i64)) } case reflect.TypeOf(basetypes.ObjectValue{}): fmt.Printf("have an object: %s\n", f.Name) resField := responseValue.FieldByName(f.Name) if !resField.IsZero() { for z := 0; z < field.Type.Elem().NumField(); z++ { rF := field.Type.Elem().Field(z) fmt.Printf("field: %s (%s)\n", rF.Name, rF.Type) } } else { fmt.Printf("field is zero") } } } } return nil }