code: func (cMgr *ConfigurationManager) handleStruct(rValue reflect.Value, tagName string) error {
  	structType := rValue.Type()
  	numOfField := structType.NumField()
  
  	for i := 0; i < numOfField; i++ {
  		structField := structType.Field(i)
  		fieldValue := rValue.Field(i)
  		keyName := cMgr.getKeyName(structField.Name, structField.Tag)
  		if keyName == ignoreField {
  			return nil
  		}
  
  		switch structField.Type.Kind() {
  		case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  			reflect.Float32, reflect.Float64, reflect.Uint, reflect.Uint8, reflect.Uint16,
  			reflect.Uint32, reflect.Uint64, reflect.Bool, reflect.Interface, reflect.Array,
  			reflect.Slice:
  			if fieldValue.CanSet() {
  				err := cMgr.setValue(fieldValue, getTagKey(tagName, keyName))
  				if err != nil {
  					return err
  				}
  			}
  		case reflect.Ptr:
  			err := cMgr.handlePtr(fieldValue, getTagKey(tagName, keyName))
  			if err != nil {
  				return err
  			}
  		case reflect.Struct:
  			err := cMgr.handleStruct(fieldValue, getTagKey(tagName, keyName))
  			if err != nil {
  				return err
  			}
  		case reflect.Map:
  			err := cMgr.handleMap(rValue, fieldValue, getTagKey(tagName, keyName))
  			if err != nil {
  				return err
  			}
  		case reflect.Uintptr, reflect.Complex64, reflect.Complex128, reflect.Chan, reflect.Func,
  			reflect.UnsafePointer:
  			// ignore
  		}
  	}
  
  	return nil
  }
docs: // handle struct type object