github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/config/validation/validation.go (about)

     1  package validation
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  )
     8  
     9  // FindEmptyStringsInConfigStruct finds empty strings in a struct.
    10  // In case the struct contains other nested structs, these struct are also checked.
    11  func FindEmptyStringsInConfigStruct(v interface{}) ([]string, error) {
    12  	emptyStrings := []string{}
    13  	if reflect.ValueOf(v).Kind() != reflect.Struct {
    14  		return emptyStrings, fmt.Errorf("'%v' (%T) is not a struct", v, v)
    15  	}
    16  	err := findNestedEmptyStrings(v, &emptyStrings, []string{})
    17  	return emptyStrings, err
    18  }
    19  
    20  func findNestedEmptyStrings(v interface{}, emptyStrings *[]string, prefix []string) error {
    21  	fields := reflect.TypeOf(v)
    22  	values := reflect.ValueOf(v)
    23  	for i := 0; i < fields.NumField(); i++ {
    24  		switch values.Field(i).Kind() {
    25  		case reflect.String:
    26  			if len(values.Field(i).String()) == 0 {
    27  				*emptyStrings = append(*emptyStrings, strings.Join(append(prefix, fields.Field(i).Name), "."))
    28  			}
    29  		case reflect.Struct:
    30  			err := findNestedEmptyStrings(values.Field(i).Interface(), emptyStrings, append(prefix, fields.Field(i).Name))
    31  			if err != nil {
    32  				return err
    33  			}
    34  		case reflect.Int:
    35  		case reflect.Int32:
    36  		case reflect.Int64:
    37  		case reflect.Bool:
    38  		case reflect.Slice:
    39  		// in case someone needs more types these types can be added here
    40  		default:
    41  			return fmt.Errorf("unexpected type '%v' of field: '%v', value: '%v'",
    42  				values.Field(i).Kind(),
    43  				fields.Field(i).Name,
    44  				values.Field(i),
    45  			)
    46  		}
    47  	}
    48  	return nil
    49  }