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 }