github.heygears.com/openimsdk/tools@v0.0.49/config/validation/validation.go (about)

     1  // Copyright © 2024 OpenIM open source community. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package validation
    16  
    17  import (
    18  	"reflect"
    19  
    20  	"github.com/openimsdk/tools/errs"
    21  )
    22  
    23  // Validator defines the interface for configuration validators.
    24  type Validator interface {
    25  	Validate(config any) error
    26  }
    27  
    28  // SimpleValidator is a basic implementation of the Validator interface,
    29  // which checks if fields in the configuration satisfy basic non-zero value requirements using reflection.
    30  type SimpleValidator struct{}
    31  
    32  // NewSimpleValidator creates and returns an instance of SimpleValidator.
    33  func NewSimpleValidator() *SimpleValidator {
    34  	return &SimpleValidator{}
    35  }
    36  
    37  // Validate checks if all fields in the given configuration object are set (i.e., non-zero values).
    38  // This is a very basic implementation and may need to be extended based on specific application requirements.
    39  func (v *SimpleValidator) Validate(config any) error {
    40  	val := reflect.ValueOf(config)
    41  	if val.Kind() == reflect.Ptr {
    42  		val = val.Elem()
    43  	}
    44  
    45  	// Validation is performed only when config is a struct
    46  	if val.Kind() == reflect.Struct {
    47  		for i := 0; i < val.NumField(); i++ {
    48  			// Check if the field has a zero value
    49  			if isZeroOfUnderlyingType(val.Field(i).Interface()) {
    50  				// If it has a zero value, return an error indicating which field is unset
    51  				return errs.New("validation failed: field " + val.Type().Field(i).Name + " is zero value").Wrap()
    52  			}
    53  		}
    54  	} else {
    55  		return errs.New("validation failed: config must be a struct or a pointer to struct").Wrap()
    56  	}
    57  
    58  	return nil
    59  }
    60  
    61  // isZeroOfUnderlyingType checks if a value is the zero value of its type.
    62  func isZeroOfUnderlyingType(x any) bool {
    63  	return x == reflect.Zero(reflect.TypeOf(x)).Interface()
    64  }