github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/option/json.go (about)

     1  package option
     2  
     3  import (
     4  	"bytes"
     5  
     6  	"github.com/inazumav/sing-box/common/badjson"
     7  	"github.com/inazumav/sing-box/common/json"
     8  	"github.com/sagernet/sing/common"
     9  	E "github.com/sagernet/sing/common/exceptions"
    10  )
    11  
    12  func ToMap(v any) (*badjson.JSONObject, error) {
    13  	inputContent, err := json.Marshal(v)
    14  	if err != nil {
    15  		return nil, err
    16  	}
    17  	var content badjson.JSONObject
    18  	err = content.UnmarshalJSON(inputContent)
    19  	if err != nil {
    20  		return nil, err
    21  	}
    22  	return &content, nil
    23  }
    24  
    25  func MergeObjects(objects ...any) (*badjson.JSONObject, error) {
    26  	var content badjson.JSONObject
    27  	for _, object := range objects {
    28  		objectMap, err := ToMap(object)
    29  		if err != nil {
    30  			return nil, err
    31  		}
    32  		content.PutAll(objectMap)
    33  	}
    34  	return &content, nil
    35  }
    36  
    37  func MarshallObjects(objects ...any) ([]byte, error) {
    38  	objects = common.FilterNotNil(objects)
    39  	if len(objects) == 1 {
    40  		return json.Marshal(objects[0])
    41  	}
    42  	content, err := MergeObjects(objects...)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  	return content.MarshalJSON()
    47  }
    48  
    49  func UnmarshallExcluded(inputContent []byte, parentObject any, object any) error {
    50  	parentContent, err := ToMap(parentObject)
    51  	if err != nil {
    52  		return err
    53  	}
    54  	var content badjson.JSONObject
    55  	err = content.UnmarshalJSON(inputContent)
    56  	if err != nil {
    57  		return err
    58  	}
    59  	for _, key := range parentContent.Keys() {
    60  		content.Remove(key)
    61  	}
    62  	if object == nil {
    63  		if content.IsEmpty() {
    64  			return nil
    65  		}
    66  		return E.New("unexpected key: ", content.Keys()[0])
    67  	}
    68  	inputContent, err = content.MarshalJSON()
    69  	if err != nil {
    70  		return err
    71  	}
    72  	decoder := json.NewDecoder(bytes.NewReader(inputContent))
    73  	decoder.DisallowUnknownFields()
    74  	return decoder.Decode(object)
    75  }