Ai
1 Star 0 Fork 1

go-genie/httptransport

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
transformer_super.go 2.93 KB
一键复制 编辑 原始数据 按行查看 历史
文兄 提交于 2025-06-17 15:56 +08:00 . init
package transformers
import (
"context"
"io"
"reflect"
pkgerrors "github.com/pkg/errors"
validatorerrors "gitee.com/go-genie/httptransport/validator"
reflectx "gitee.com/go-genie/xx/reflect"
)
func NewTransformerSuper(transformer Transformer, opt *CommonTransformOption) *TransformerSuper {
return &TransformerSuper{
transformer: transformer,
CommonTransformOption: *opt,
}
}
type TransformerSuper struct {
transformer Transformer
CommonTransformOption
}
func (t *TransformerSuper) EncodeTo(ctx context.Context, w io.Writer, v interface{}) error {
rv, ok := v.(reflect.Value)
if !ok {
rv = reflect.ValueOf(v)
}
if t.Explode {
rv = reflectx.Indirect(rv)
// for create slice
if canSetN, ok := w.(interface{ SetN(n int) }); ok {
canSetN.SetN(rv.Len())
}
if writerCreator, ok := w.(CanNextWriter); ok {
errSet := validatorerrors.NewErrorSet()
for i := 0; i < rv.Len(); i++ {
w := writerCreator.NextWriter()
if err := t.transformer.EncodeTo(ctx, w, rv.Index(i)); err != nil {
errSet.AddErr(err, i)
}
}
return errSet.Err()
}
return nil
}
// should skip empty value when omitempty
if !(t.Omitempty && reflectx.IsEmptyValue(rv)) {
writerCreator, ok := w.(CanNextWriter)
if ok {
return t.transformer.EncodeTo(ctx, writerCreator.NextWriter(), rv)
}
return t.transformer.EncodeTo(ctx, w, rv)
}
return nil
}
func (t *TransformerSuper) DecodeFrom(ctx context.Context, r io.Reader, v interface{}) error {
if rv, ok := v.(reflect.Value); ok {
v = rv.Interface()
}
if reflect.TypeOf(v).Kind() != reflect.Ptr {
return pkgerrors.Errorf("decode target must be ptr value")
}
if t.Explode {
lenOfValues := 0
if canLen, ok := r.(interface{ Len() int }); ok {
lenOfValues = canLen.Len()
}
if lenOfValues == 0 {
return nil
}
if x, ok := v.(*[]string); ok {
if canInterface, ok := r.(CanInterface); ok {
if values, ok := canInterface.Interface().([]string); ok {
*x = values
return nil
}
}
}
sliceOrArrayRv := reflectx.Indirect(reflect.ValueOf(v))
if sliceOrArrayRv.Kind() == reflect.Slice {
// only slice should set be set
sliceOrArrayRv.Set(reflect.MakeSlice(sliceOrArrayRv.Type(), lenOfValues, lenOfValues))
}
readerCreator, ok := r.(CanNextReader)
if !ok {
return nil
}
es := validatorerrors.NewErrorSet()
for i := 0; i < sliceOrArrayRv.Len(); i++ {
if i < lenOfValues {
itemValue := sliceOrArrayRv.Index(i)
// ignore when values length greater than array len
if err := t.transformer.DecodeFrom(ctx, readerCreator.NextReader(), itemValue.Addr()); err != nil {
es.AddErr(err, i)
}
}
}
return es.Err()
}
readerCreator, ok := r.(CanNextReader)
if ok {
return t.transformer.DecodeFrom(ctx, readerCreator.NextReader(), v)
}
return t.transformer.DecodeFrom(ctx, r, v)
}
type CanNextWriter interface {
NextWriter() io.Writer
}
type CanNextReader interface {
NextReader() io.Reader
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/go-genie/httptransport.git
git@gitee.com:go-genie/httptransport.git
go-genie
httptransport
httptransport
v1.1.4

搜索帮助