json.go 1.6 KB

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