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

     1  package jsoni
     2  
     3  import (
     4  	"context"
     5  	"reflect"
     6  	"unsafe"
     7  )
     8  
     9  type objectLazyAny struct {
    10  	baseAny
    11  	cfg *frozenConfig
    12  	buf []byte
    13  	err error
    14  }
    15  
    16  func (any *objectLazyAny) ValueType() ValueType { return ObjectValue }
    17  func (any *objectLazyAny) MustBeValid() Any     { return any }
    18  func (any *objectLazyAny) LastError() error     { return any.err }
    19  func (any *objectLazyAny) ToBool() bool         { return true }
    20  func (any *objectLazyAny) ToInt() int           { return 0 }
    21  func (any *objectLazyAny) ToInt32() int32       { return 0 }
    22  func (any *objectLazyAny) ToInt64() int64       { return 0 }
    23  func (any *objectLazyAny) ToUint() uint         { return 0 }
    24  func (any *objectLazyAny) ToUint32() uint32     { return 0 }
    25  func (any *objectLazyAny) ToUint64() uint64     { return 0 }
    26  func (any *objectLazyAny) ToFloat32() float32   { return 0 }
    27  func (any *objectLazyAny) ToFloat64() float64   { return 0 }
    28  func (any *objectLazyAny) ToString() string     { return *(*string)(unsafe.Pointer(&any.buf)) }
    29  
    30  func (any *objectLazyAny) ToVal(ctx context.Context, obj interface{}) {
    31  	iter := any.cfg.BorrowIterator(any.buf)
    32  	defer any.cfg.ReturnIterator(iter)
    33  	iter.ReadVal(ctx, obj)
    34  }
    35  
    36  func (any *objectLazyAny) Get(path ...interface{}) Any {
    37  	if len(path) == 0 {
    38  		return any
    39  	}
    40  	switch firstPath := path[0].(type) {
    41  	case string:
    42  		iter := any.cfg.BorrowIterator(any.buf)
    43  		defer any.cfg.ReturnIterator(iter)
    44  		valueBytes := locateObjectField(iter, firstPath)
    45  		if valueBytes == nil {
    46  			return newInvalidAny(path)
    47  		}
    48  		iter.ResetBytes(valueBytes)
    49  		return locatePath(iter, path[1:])
    50  	case int32:
    51  		if '*' == firstPath {
    52  			mappedAll := map[string]Any{}
    53  			iter := any.cfg.BorrowIterator(any.buf)
    54  			defer any.cfg.ReturnIterator(iter)
    55  			iter.ReadMapCB(func(iter *Iterator, field string) bool {
    56  				mapped := locatePath(iter, path[1:])
    57  				if mapped.ValueType() != InvalidValue {
    58  					mappedAll[field] = mapped
    59  				}
    60  				return true
    61  			})
    62  			return wrapMap(mappedAll)
    63  		}
    64  		return newInvalidAny(path)
    65  	default:
    66  		return newInvalidAny(path)
    67  	}
    68  }
    69  
    70  func (any *objectLazyAny) Keys() []string {
    71  	var keys []string
    72  	iter := any.cfg.BorrowIterator(any.buf)
    73  	defer any.cfg.ReturnIterator(iter)
    74  	iter.ReadMapCB(func(iter *Iterator, field string) bool {
    75  		iter.Skip()
    76  		keys = append(keys, field)
    77  		return true
    78  	})
    79  	return keys
    80  }
    81  
    82  func (any *objectLazyAny) Size() int {
    83  	size := 0
    84  	iter := any.cfg.BorrowIterator(any.buf)
    85  	defer any.cfg.ReturnIterator(iter)
    86  	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
    87  		iter.Skip()
    88  		size++
    89  		return true
    90  	})
    91  	return size
    92  }
    93  
    94  func (any *objectLazyAny) WriteTo(_ context.Context, stream *Stream) {
    95  	stream.Write(any.buf)
    96  }
    97  
    98  func (any *objectLazyAny) GetInterface(ctx context.Context) interface{} {
    99  	iter := any.cfg.BorrowIterator(any.buf)
   100  	defer any.cfg.ReturnIterator(iter)
   101  	return iter.Read(ctx)
   102  }
   103  
   104  type objectAny struct {
   105  	baseAny
   106  	err error
   107  	val reflect.Value
   108  }
   109  
   110  func wrapStruct(val interface{}) *objectAny {
   111  	return &objectAny{baseAny{}, nil, reflect.ValueOf(val)}
   112  }
   113  
   114  func (any *objectAny) ValueType() ValueType { return ObjectValue }
   115  func (any *objectAny) MustBeValid() Any     { return any }
   116  func (any *objectAny) Parse() *Iterator     { return nil }
   117  func (any *objectAny) LastError() error     { return any.err }
   118  func (any *objectAny) ToBool() bool         { return any.val.NumField() != 0 }
   119  func (any *objectAny) ToInt() int           { return 0 }
   120  func (any *objectAny) ToInt32() int32       { return 0 }
   121  func (any *objectAny) ToInt64() int64       { return 0 }
   122  func (any *objectAny) ToUint() uint         { return 0 }
   123  func (any *objectAny) ToUint32() uint32     { return 0 }
   124  func (any *objectAny) ToUint64() uint64     { return 0 }
   125  func (any *objectAny) ToFloat32() float32   { return 0 }
   126  func (any *objectAny) ToFloat64() float64   { return 0 }
   127  
   128  func (any *objectAny) ToString() string {
   129  	str, err := MarshalToString(any.val.Interface())
   130  	any.err = err
   131  	return str
   132  }
   133  
   134  func (any *objectAny) Get(path ...interface{}) Any {
   135  	if len(path) == 0 {
   136  		return any
   137  	}
   138  	switch firstPath := path[0].(type) {
   139  	case string:
   140  		field := any.val.FieldByName(firstPath)
   141  		if !field.IsValid() {
   142  			return newInvalidAny(path)
   143  		}
   144  		return Wrap(field.Interface())
   145  	case int32:
   146  		if '*' == firstPath {
   147  			mappedAll := map[string]Any{}
   148  			for i := 0; i < any.val.NumField(); i++ {
   149  				field := any.val.Field(i)
   150  				if field.CanInterface() {
   151  					mapped := Wrap(field.Interface()).Get(path[1:]...)
   152  					if mapped.ValueType() != InvalidValue {
   153  						mappedAll[any.val.Type().Field(i).Name] = mapped
   154  					}
   155  				}
   156  			}
   157  			return wrapMap(mappedAll)
   158  		}
   159  		return newInvalidAny(path)
   160  	default:
   161  		return newInvalidAny(path)
   162  	}
   163  }
   164  
   165  func (any *objectAny) Keys() []string {
   166  	keys := make([]string, 0, any.val.NumField())
   167  	for i := 0; i < any.val.NumField(); i++ {
   168  		keys = append(keys, any.val.Type().Field(i).Name)
   169  	}
   170  	return keys
   171  }
   172  
   173  func (any *objectAny) Size() int {
   174  	return any.val.NumField()
   175  }
   176  
   177  func (any *objectAny) WriteTo(ctx context.Context, stream *Stream) {
   178  	stream.WriteVal(ctx, any.val)
   179  }
   180  
   181  func (any *objectAny) GetInterface(context.Context) interface{} {
   182  	return any.val.Interface()
   183  }
   184  
   185  type mapAny struct {
   186  	baseAny
   187  	err error
   188  	val reflect.Value
   189  }
   190  
   191  func wrapMap(val interface{}) *mapAny    { return &mapAny{baseAny{}, nil, reflect.ValueOf(val)} }
   192  func (any *mapAny) ValueType() ValueType { return ObjectValue }
   193  func (any *mapAny) MustBeValid() Any     { return any }
   194  func (any *mapAny) Parse() *Iterator     { return nil }
   195  func (any *mapAny) LastError() error     { return any.err }
   196  func (any *mapAny) ToBool() bool         { return true }
   197  func (any *mapAny) ToInt() int           { return 0 }
   198  func (any *mapAny) ToInt32() int32       { return 0 }
   199  func (any *mapAny) ToInt64() int64       { return 0 }
   200  func (any *mapAny) ToUint() uint         { return 0 }
   201  func (any *mapAny) ToUint32() uint32     { return 0 }
   202  func (any *mapAny) ToUint64() uint64     { return 0 }
   203  func (any *mapAny) ToFloat32() float32   { return 0 }
   204  func (any *mapAny) ToFloat64() float64   { return 0 }
   205  
   206  func (any *mapAny) ToString() string {
   207  	str, err := MarshalToString(any.val.Interface())
   208  	any.err = err
   209  	return str
   210  }
   211  
   212  func (any *mapAny) Get(path ...interface{}) Any {
   213  	if len(path) == 0 {
   214  		return any
   215  	}
   216  	switch firstPath := path[0].(type) {
   217  	case int32:
   218  		if '*' == firstPath {
   219  			mappedAll := map[string]Any{}
   220  			for _, key := range any.val.MapKeys() {
   221  				keyAsStr := key.String()
   222  				element := Wrap(any.val.MapIndex(key).Interface())
   223  				mapped := element.Get(path[1:]...)
   224  				if mapped.ValueType() != InvalidValue {
   225  					mappedAll[keyAsStr] = mapped
   226  				}
   227  			}
   228  			return wrapMap(mappedAll)
   229  		}
   230  		return newInvalidAny(path)
   231  	default:
   232  		value := any.val.MapIndex(reflect.ValueOf(firstPath))
   233  		if !value.IsValid() {
   234  			return newInvalidAny(path)
   235  		}
   236  		return Wrap(value.Interface())
   237  	}
   238  }
   239  
   240  func (any *mapAny) Keys() []string {
   241  	keys := make([]string, 0, any.val.Len())
   242  	for _, key := range any.val.MapKeys() {
   243  		keys = append(keys, key.String())
   244  	}
   245  	return keys
   246  }
   247  
   248  func (any *mapAny) Size() int                                   { return any.val.Len() }
   249  func (any *mapAny) WriteTo(ctx context.Context, stream *Stream) { stream.WriteVal(ctx, any.val) }
   250  func (any *mapAny) GetInterface(context.Context) interface{}    { return any.val.Interface() }