github.com/searKing/golang/go@v1.2.117/encoding/json/concat.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package json 6 7 import ( 8 "bytes" 9 "encoding/json" 10 "fmt" 11 ) 12 13 func Join(bufa []byte, bufbs ...[]byte) ([]byte, error) { 14 if len(bufbs) == 0 { 15 return bufa, nil 16 } 17 // append bs to b. 18 bufb, err := Join(bufbs[0], bufbs[1:]...) 19 if err != nil { 20 return nil, err 21 } 22 23 // Concatenate public and private claim JSON objects. 24 if !bytes.HasSuffix(bufa, []byte{'}'}) { 25 return nil, fmt.Errorf("json: invalid JSON %s", bufa) 26 } 27 if !bytes.HasPrefix(bufb, []byte{'{'}) { 28 return nil, fmt.Errorf("json: invalid JSON %s", bufb) 29 } 30 bufa[len(bufa)-1] = ',' // Replace closing curly brace with a comma. 31 bufa = append(bufa, bufb[1:]...) // Append vb after va. 32 return bufa, nil 33 } 34 35 // MarshalConcat returns the JSON encoding of va, vbs..., 36 // ignore conflict keys of json if meet later. 37 func MarshalConcat(va any, vbs ...any) ([]byte, error) { 38 unique, err := marshalConcat(nil, va, vbs...) 39 if err != nil { 40 return nil, err 41 } 42 return json.Marshal(unique) 43 } 44 45 func marshalConcat(unique map[string]any, va any, vbs ...any) (map[string]any, error) { 46 bufa, err := json.Marshal(va) 47 if err != nil { 48 return unique, err 49 } 50 51 // Marshal vbs and then append it to uniqueMap. 52 var mapa map[string]any 53 if err := json.Unmarshal(bufa, &mapa); err != nil { 54 return unique, err 55 } 56 if unique == nil { 57 unique = map[string]any{} 58 } 59 // unique 60 for k, v := range mapa { 61 if _, ok := unique[k]; ok { 62 continue 63 } 64 unique[k] = v 65 } 66 67 if len(vbs) == 0 { 68 return unique, nil 69 } 70 if len(vbs) == 1 { 71 return marshalConcat(unique, vbs[0]) 72 } 73 return marshalConcat(unique, vbs[0], vbs[1:]) 74 } 75 76 func MarshalIndentConcat(va any, prefix, indent string, vbs ...any) ([]byte, error) { 77 b, err := MarshalConcat(va, vbs) 78 if err != nil { 79 return nil, err 80 } 81 var buf bytes.Buffer 82 err = json.Indent(&buf, b, prefix, indent) 83 if err != nil { 84 return nil, err 85 } 86 return buf.Bytes(), nil 87 } 88 89 // Unmarshal parses the JSON-encoded data and stores the result 90 // in the value pointed to by v. If v is nil or not a pointer, 91 // Unmarshal returns an InvalidUnmarshalError. 92 // ignore conflict keys of json if meet later. 93 func UnmarshalConcat(data []byte, va any, vbs ...any) error { 94 var unique map[string]any 95 err := json.Unmarshal(data, &unique) 96 if err != nil { 97 return err 98 } 99 return unmarshalConcat(unique, va, vbs...) 100 } 101 102 func unmarshalConcat(unique map[string]any, va any, vbs ...any) error { 103 data, err := json.Marshal(unique) 104 if err != nil { 105 return err 106 } 107 if err := json.Unmarshal(data, va); err != nil { 108 return err 109 } 110 if len(vbs) == 0 { 111 return nil 112 } 113 dataa, err := json.Marshal(va) 114 if err != nil { 115 return err 116 } 117 118 var mapa map[string]any 119 if err := json.Unmarshal(dataa, &mapa); err != nil { 120 return err 121 } 122 123 // unique 124 for k, _ := range mapa { 125 delete(unique, k) 126 } 127 128 if len(vbs) == 0 { 129 return nil 130 } 131 if len(vbs) == 1 { 132 return unmarshalConcat(unique, vbs[0]) 133 } 134 return unmarshalConcat(unique, vbs[0], vbs[1:]) 135 }