github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/cry/read.go (about)

     1  package cry
     2  
     3  import "reflect"
     4  
     5  const (
     6  	// GOCRYPT is variable tag field for gocrypt
     7  	GOCRYPT = "gocrypt"
     8  )
     9  
    10  type changesValue func(string, string) (string, error)
    11  
    12  func read(v interface{}, encDec changesValue) error {
    13  	return inspectField(reflect.ValueOf(v), encDec)
    14  }
    15  
    16  func inspectField(val reflect.Value, encDec changesValue) error {
    17  	if val.Kind() == reflect.Interface && !val.IsNil() {
    18  		elm := val.Elem()
    19  		if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
    20  			val = elm
    21  		}
    22  	}
    23  	if val.Kind() == reflect.Ptr {
    24  		val = val.Elem()
    25  	}
    26  	typeOfS := val.Type()
    27  	for i := 0; i < val.NumField(); i++ {
    28  		valueField := val.Field(i)
    29  		if valueField.Kind() == reflect.Interface && !valueField.IsNil() {
    30  			elm := valueField.Elem()
    31  			if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
    32  				valueField = elm
    33  			}
    34  		}
    35  
    36  		if valueField.Kind() == reflect.Ptr {
    37  			valueField = valueField.Elem()
    38  		}
    39  
    40  		if valueField.Kind() == reflect.String {
    41  			if valueField.CanSet() {
    42  				valueTag := typeOfS.Field(i).Tag.Get(GOCRYPT)
    43  				if len(valueTag) > 0 {
    44  					encvalue, err := encDec(valueTag, valueField.String())
    45  					if err != nil {
    46  						return err
    47  					}
    48  					valueField.SetString(encvalue)
    49  				}
    50  			}
    51  		}
    52  
    53  		if valueField.Kind() == reflect.Struct {
    54  			if err := inspectField(valueField, encDec); err != nil {
    55  				return err
    56  			}
    57  		}
    58  	}
    59  
    60  	return nil
    61  }