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  }