Skip to content

Commit

Permalink
Extract CheckStructuralSubset implementation.
Browse files Browse the repository at this point in the history
CheckStructuralSubset function has path passed for better error
reporting. This implementation detail shouldn't be exposed in public
API.
  • Loading branch information
kl52752 committed Jan 26, 2024
1 parent b02fabb commit e5919bd
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
20 changes: 13 additions & 7 deletions pkg/cloud/api/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,14 @@ func checkSchema(t reflect.Type) error {

// CheckStructuralSubset checks if type From is the subset of To type. Type is a
// subset of another if it contains fields with the same type and name. This
// function is not symmetric. Path parameter is used for better error reporting.
func CheckStructuralSubset(p Path, from, to reflect.Type) error {
// function is not symmetric.
func CheckStructuralSubset(from, to reflect.Type) error {
return checkStructuralSubsetImpl(Path{}, from, to)
}

// checkStructuralSubsetImpl this is recursive function to check if type From is
// a subset of To type. Path parameter is used for better error reporting.
func checkStructuralSubsetImpl(p Path, from, to reflect.Type) error {
if from.Kind() != to.Kind() {
return fmt.Errorf("%s has different type: %v != %v", p, from.Kind(), to.Kind())
}
Expand All @@ -184,7 +190,7 @@ func CheckStructuralSubset(p Path, from, to reflect.Type) error {
}
switch from.Kind() {
case reflect.Pointer:
return CheckStructuralSubset(p.Pointer(), from.Elem(), to.Elem())
return checkStructuralSubsetImpl(p.Pointer(), from.Elem(), to.Elem())

case reflect.Struct:
for i := 0; i < from.NumField(); i++ {
Expand All @@ -193,22 +199,22 @@ func CheckStructuralSubset(p Path, from, to reflect.Type) error {
if !exist {
return fmt.Errorf("%s: type %T does not have field %v", p.String(), to, af.Name)
}
if err := CheckStructuralSubset(p.Field(af.Name), af.Type, bf.Type); err != nil {
if err := checkStructuralSubsetImpl(p.Field(af.Name), af.Type, bf.Type); err != nil {
return err
}
}
return nil

case reflect.Slice, reflect.Array:
return CheckStructuralSubset(p.AnySliceIndex(), from.Elem(), to.Elem())
return checkStructuralSubsetImpl(p.AnySliceIndex(), from.Elem(), to.Elem())

case reflect.Map:
path := p.AnyMapIndex()
err := CheckStructuralSubset(path, from.Key(), to.Key())
err := checkStructuralSubsetImpl(path, from.Key(), to.Key())
if err != nil {
return err
}
return CheckStructuralSubset(path, from.Elem(), to.Elem())
return checkStructuralSubsetImpl(path, from.Elem(), to.Elem())
}
return fmt.Errorf("%s Unsupported type %v", p.String(), from.Kind())
}
2 changes: 1 addition & 1 deletion pkg/cloud/api/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ func TestConvertToT(t *testing.T) {
},
} {
t.Run(tc.name, func(t *testing.T) {
err := CheckStructuralSubset(Path{}, reflect.TypeOf(tc.a), reflect.TypeOf(tc.b))
err := CheckStructuralSubset(reflect.TypeOf(tc.a), reflect.TypeOf(tc.b))
gotErr := err != nil
if gotErr != tc.wantErr {
t.Fatalf("CheckStructuralSubset() = %v; gotErr = %t, want %t", err, gotErr, tc.wantErr)
Expand Down
2 changes: 1 addition & 1 deletion pkg/cloud/api/mutable_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func (u *mutableResource[GA, Alpha, Beta]) CheckSchema() error {

func checkSubsetOf[T1 any, T2 any](t1 *T1, t2 *T2) error {

return CheckStructuralSubset(Path{}, reflect.TypeOf(t1), reflect.TypeOf(t2))
return CheckStructuralSubset(reflect.TypeOf(t1), reflect.TypeOf(t2))
}

func (u *mutableResource[GA, Alpha, Beta]) ResourceID() *cloud.ResourceID { return u.resourceID }
Expand Down

0 comments on commit e5919bd

Please sign in to comment.