github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/state/merge.go (about)

     1  package state
     2  
     3  import (
     4  	"reflect"
     5  )
     6  
     7  // Merge merges the states of the services that have been scanned into a single state.
     8  // if a service has data on both a and b, the service data from b will be preferred.
     9  func (a *State) Merge(b *State) (*State, error) {
    10  	var output State
    11  
    12  	aVal := reflect.ValueOf(a).Elem()
    13  	bVal := reflect.ValueOf(b).Elem()
    14  	outputVal := reflect.ValueOf(&output).Elem()
    15  
    16  	stateType := reflect.ValueOf(a).Elem().Type()
    17  	for i := 0; i < stateType.NumField(); i++ {
    18  		field := stateType.Field(i)
    19  		if !field.IsExported() {
    20  			continue
    21  		}
    22  		if field.Type.Kind() != reflect.Struct {
    23  			continue
    24  		}
    25  		for j := 0; j < field.Type.NumField(); j++ {
    26  			serviceField := field.Type.Field(j)
    27  			if !serviceField.IsExported() {
    28  				continue
    29  			}
    30  			if serviceField.Type.Kind() != reflect.Struct {
    31  				continue
    32  			}
    33  			if !bVal.Field(i).Field(j).IsZero() {
    34  				outputVal.Field(i).Field(j).Set(bVal.Field(i).Field(j))
    35  			} else {
    36  				outputVal.Field(i).Field(j).Set(aVal.Field(i).Field(j))
    37  			}
    38  		}
    39  	}
    40  
    41  	normalised := outputVal.Interface().(State)
    42  	return &normalised, nil
    43  }