package rpc import ( "errors" "fmt" "reflect" ) var stringType = reflect.TypeOf("") type ValueParserBuilder struct { } func (builder *ValueParserBuilder) parseJsonBoolean(jsonValue interface{}, valueName string) (interface{}, error) { if jsonValue == nil { return nil, errors.New(fmt.Sprintf("%s 不能为空!", valueName)) } else if value, ok := jsonValue.(bool); !ok { return nil, errors.New(fmt.Sprintf("%s 无法解析!源类型:%v,目标类型:Bool.", valueName, reflect.TypeOf(jsonValue))) } else { return value, nil } } func (builder *ValueParserBuilder) parseJsonString(jsonValue interface{}, valueName string) (interface{}, error) { if jsonValue == nil { return "", nil } else if value, ok := jsonValue.(string); !ok { return nil, errors.New(fmt.Sprintf("%s 无法解析!源类型:%v,目标类型:String.", valueName, reflect.TypeOf(jsonValue))) } else { return value, nil } } func (builder *ValueParserBuilder) parseJsonNumber(jsonValue interface{}, valueName string) (float64, error) { if jsonValue == nil { return 0, errors.New(fmt.Sprintf("%s 不能为空!", valueName)) } else if value, ok := jsonValue.(float64); !ok { return 0, errors.New(fmt.Sprintf("%s 无法解析!源类型:%v,目标类型:Number.", valueName, reflect.TypeOf(jsonValue))) } else { return value, nil } } func (builder *ValueParserBuilder) parseJsonArray(jsonValue interface{}, valueName string) ([]interface{}, error) { if jsonValue == nil { return nil, errors.New(fmt.Sprintf("%s 不能为空!", valueName)) } else if items, ok := jsonValue.([]interface{}); !ok { return nil, errors.New(fmt.Sprintf("%s 无法解析!源类型:%v,目标类型:Array.", valueName, reflect.TypeOf(jsonValue))) } else { return items, nil } } func (builder *ValueParserBuilder) parseJsonObject(jsonValue interface{}, valueName string) (map[string]interface{}, error) { if jsonValue == nil { return nil, errors.New(fmt.Sprintf("%s 不能为空!", valueName)) } else if jsonObject, ok := jsonValue.(map[string]interface{}); !ok { return nil, errors.New(fmt.Sprintf("%s 无法解析!源类型:%v,目标类型:Object.", valueName, reflect.TypeOf(jsonValue))) } else { return jsonObject, nil } } func (builder *ValueParserBuilder) parseUnsignedInteger(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return uint(value), nil } } func (builder *ValueParserBuilder) parseUnsignedInteger8(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return uint8(value), nil } } func (builder *ValueParserBuilder) parseUnsignedInteger16(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return uint16(value), nil } } func (builder *ValueParserBuilder) parseUnsignedInteger32(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return uint32(value), nil } } func (builder *ValueParserBuilder) parseUnsignedInteger64(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return uint64(value), nil } } func (builder *ValueParserBuilder) parseInteger(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return int(value), nil } } func (builder *ValueParserBuilder) parseInteger8(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return int8(value), nil } } func (builder *ValueParserBuilder) parseInteger16(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return int16(value), nil } } func (builder *ValueParserBuilder) parseInteger32(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return int32(value), nil } } func (builder *ValueParserBuilder) parseInteger64(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return int64(value), nil } } func (builder *ValueParserBuilder) parseFloat32(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return float32(value), nil } } func (builder *ValueParserBuilder) parseFloat64(jsonValue interface{}, valueName string) (interface{}, error) { if value, err := builder.parseJsonNumber(jsonValue, valueName); err != nil { return nil, err } else { return value, nil } } func (builder *ValueParserBuilder) buildMapParser(valueParser valueParser, valueType reflect.Type) valueParser { return func(jsonValue interface{}, valueName string) (interface{}, error) { if jsonObject, err := builder.parseJsonObject(jsonValue, valueName); err != nil { return reflect.Zero(reflect.MapOf(stringType, valueType)).Interface(), nil } else { result := reflect.MakeMapWithSize(reflect.MapOf(stringType, valueType), len(jsonObject)) for key, value := range jsonObject { if value, err := valueParser(value, fmt.Sprintf("%s[%s]", valueName, key)); err != nil { return nil, err } else { result.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(value)) } } return result.Interface(), nil } } } func (builder *ValueParserBuilder) buildSliceParser(itemParser valueParser, elementType reflect.Type) valueParser { return func(jsonValue interface{}, valueName string) (interface{}, error) { if jsonArray, err := builder.parseJsonArray(jsonValue, valueName); err != nil { return reflect.Zero(reflect.SliceOf(elementType)).Interface(), nil } else { slice := reflect.MakeSlice(reflect.SliceOf(elementType), len(jsonArray), len(jsonArray)) for index, item := range jsonArray { if value, err := itemParser(item, fmt.Sprintf("%s[%d]", valueName, index)); err != nil { return nil, err } else { slice.Index(index).Set(reflect.ValueOf(value)) } } return slice.Interface(), nil } } } func (builder *ValueParserBuilder) buildArrayParser(itemParser valueParser, length int, elementType reflect.Type) valueParser { return func(jsonValue interface{}, valueName string) (interface{}, error) { if jsonArray, err := builder.parseJsonArray(jsonValue, valueName); err != nil { return nil, err } else if len(jsonArray) != length { return nil, errors.New(fmt.Sprintf("%s 数组长度匹配!期望长度:%d,实际长度:%d.", valueName, length, len(jsonArray))) } else { array := reflect.New(reflect.ArrayOf(length, elementType)).Elem() for index := 0; index < length; index++ { if value, err := itemParser(jsonArray[index], fmt.Sprintf("%s[%d]", valueName, index)); err != nil { return nil, err } else { array.Index(index).Set(reflect.ValueOf(value)) } } return array.Interface(), nil } } } func (builder *ValueParserBuilder) buildPointerParser(itemParser valueParser, elementType reflect.Type) valueParser { return func(jsonValue interface{}, valueName string) (interface{}, error) { if jsonValue == nil { return reflect.Zero(reflect.PtrTo(elementType)).Interface(), nil } else if value, err := itemParser(jsonValue, valueName); err != nil { return nil, err } else { pointer := reflect.New(elementType) pointer.Elem().Set(reflect.ValueOf(value)) return pointer.Interface(), nil } } } func (builder *ValueParserBuilder) buildStructParser(valueID string, structType reflect.Type) (valueParser, error) { fieldCount := structType.NumField() parsers := make(map[string]valueParser, fieldCount) for i := 0; i < fieldCount; i++ { field := structType.Field(i) if parameterParser, err := builder.Build(fmt.Sprintf("%s.%s", valueID, field.Name), field.Type); err != nil { return nil, err } else { parsers[field.Name] = parameterParser } } return func(jsonValue interface{}, valueName string) (interface{}, error) { structValue := reflect.New(structType).Elem() for fieldName, parser := range parsers { field := structValue.FieldByName(fieldName) if !field.IsValid() { return nil, errors.New(fmt.Sprintf("%s 没有找到字段:%v.%s", valueName, structType, fieldName)) } if jsonObject, err := builder.parseJsonObject(jsonValue, valueName); err != nil { return nil, err } else if value, err := parser(jsonObject[fieldName], fmt.Sprintf("%s.%s", valueName, fieldName)); err != nil { return nil, err } else { field.Set(reflect.ValueOf(value)) } } return structValue.Interface(), nil }, nil } func (builder *ValueParserBuilder) Build(valueID string, valueType reflect.Type) (valueParser, error) { switch valueType.Kind() { //case reflect.Invalid: case reflect.Bool: return builder.parseJsonBoolean, nil case reflect.Int: return builder.parseInteger, nil case reflect.Int8: return builder.parseInteger8, nil case reflect.Int16: return builder.parseInteger16, nil case reflect.Int32: return builder.parseInteger32, nil case reflect.Int64: return builder.parseInteger64, nil case reflect.Uint: return builder.parseUnsignedInteger, nil case reflect.Uint8: return builder.parseUnsignedInteger8, nil case reflect.Uint16: return builder.parseUnsignedInteger16, nil case reflect.Uint32: return builder.parseUnsignedInteger32, nil case reflect.Uint64: return builder.parseUnsignedInteger64, nil //case reflect.Uintptr: case reflect.Float32: return builder.parseFloat32, nil case reflect.Float64: return builder.parseFloat64, nil //case reflect.Complex64: //case reflect.Complex128: case reflect.Array: parser, err := builder.Build(valueID, valueType.Elem()) if err != nil { return nil, err } else { return builder.buildArrayParser(parser, valueType.Len(), valueType.Elem()), nil } //case reflect.Chan: //case reflect.Func: //case reflect.Interface: case reflect.Map: if valueType.Key().Kind() != reflect.String { return nil, errors.New(fmt.Sprintf("*map[%s]%s", valueType.Key().Name(), valueType.Elem().Name())) } valuerParser, err := builder.Build(valueID, valueType.Elem()) if err != nil { return nil, err } else { return builder.buildMapParser(valuerParser, valueType.Elem()), nil } case reflect.Ptr: parser, err := builder.Build(valueID, valueType.Elem()) if err != nil { return nil, err } else { return builder.buildPointerParser(parser, valueType.Elem()), nil } case reflect.Slice: parser, err := builder.Build(valueID, valueType.Elem()) if err != nil { return nil, err } else { return builder.buildSliceParser(parser, valueType.Elem()), nil } case reflect.String: return builder.parseJsonString, nil case reflect.Struct: parser, err := builder.buildStructParser(valueID, valueType) if err != nil { return nil, err } else { return parser, nil } //case reflect.UnsafePointer: default: return nil, errors.New(fmt.Sprintf("不支持的类型: %s.%s", valueID, valueType.Name())) } }