json.go 1.6 KB

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