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() }