script.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package option
  2. import (
  3. C "github.com/sagernet/sing-box/constant"
  4. E "github.com/sagernet/sing/common/exceptions"
  5. "github.com/sagernet/sing/common/json"
  6. "github.com/sagernet/sing/common/json/badjson"
  7. "github.com/sagernet/sing/common/json/badoption"
  8. )
  9. type _ScriptSourceOptions struct {
  10. Source string `json:"source"`
  11. LocalOptions LocalScriptSource `json:"-"`
  12. RemoteOptions RemoteScriptSource `json:"-"`
  13. }
  14. type LocalScriptSource struct {
  15. Path string `json:"path"`
  16. }
  17. type RemoteScriptSource struct {
  18. URL string `json:"url"`
  19. DownloadDetour string `json:"download_detour,omitempty"`
  20. UpdateInterval badoption.Duration `json:"update_interval,omitempty"`
  21. }
  22. type ScriptSourceOptions _ScriptSourceOptions
  23. func (o ScriptSourceOptions) MarshalJSON() ([]byte, error) {
  24. var source any
  25. switch o.Source {
  26. case C.ScriptSourceTypeLocal:
  27. source = o.LocalOptions
  28. case C.ScriptSourceTypeRemote:
  29. source = o.RemoteOptions
  30. default:
  31. return nil, E.New("unknown script source: ", o.Source)
  32. }
  33. return badjson.MarshallObjects((_ScriptSourceOptions)(o), source)
  34. }
  35. func (o *ScriptSourceOptions) UnmarshalJSON(bytes []byte) error {
  36. err := json.Unmarshal(bytes, (*_ScriptSourceOptions)(o))
  37. if err != nil {
  38. return err
  39. }
  40. var source any
  41. switch o.Source {
  42. case C.ScriptSourceTypeLocal:
  43. source = &o.LocalOptions
  44. case C.ScriptSourceTypeRemote:
  45. source = &o.RemoteOptions
  46. default:
  47. return E.New("unknown script source: ", o.Source)
  48. }
  49. return json.Unmarshal(bytes, source)
  50. }
  51. // TODO: make struct in order
  52. type Script struct {
  53. ScriptSourceOptions
  54. ScriptOptions
  55. }
  56. func (s Script) MarshalJSON() ([]byte, error) {
  57. return badjson.MarshallObjects(s.ScriptSourceOptions, s.ScriptOptions)
  58. }
  59. func (s *Script) UnmarshalJSON(bytes []byte) error {
  60. err := json.Unmarshal(bytes, &s.ScriptSourceOptions)
  61. if err != nil {
  62. return err
  63. }
  64. return badjson.UnmarshallExcluded(bytes, &s.ScriptSourceOptions, &s.ScriptOptions)
  65. }
  66. type _ScriptOptions struct {
  67. Type string `json:"type"`
  68. Tag string `json:"tag"`
  69. SurgeOptions SurgeScriptOptions `json:"-"`
  70. }
  71. type ScriptOptions _ScriptOptions
  72. func (o ScriptOptions) MarshalJSON() ([]byte, error) {
  73. var v any
  74. switch o.Type {
  75. case C.ScriptTypeSurge:
  76. v = &o.SurgeOptions
  77. default:
  78. return nil, E.New("unknown script type: ", o.Type)
  79. }
  80. if v == nil {
  81. return badjson.MarshallObjects((_ScriptOptions)(o))
  82. }
  83. return badjson.MarshallObjects((_ScriptOptions)(o), v)
  84. }
  85. func (o *ScriptOptions) UnmarshalJSON(bytes []byte) error {
  86. err := json.Unmarshal(bytes, (*_ScriptOptions)(o))
  87. if err != nil {
  88. return err
  89. }
  90. var v any
  91. switch o.Type {
  92. case C.ScriptTypeSurge:
  93. v = &o.SurgeOptions
  94. case "":
  95. return E.New("missing script type")
  96. default:
  97. return E.New("unknown script type: ", o.Type)
  98. }
  99. if v == nil {
  100. // check unknown fields
  101. return json.UnmarshalDisallowUnknownFields(bytes, &_ScriptOptions{})
  102. }
  103. return badjson.UnmarshallExcluded(bytes, (*_ScriptOptions)(o), v)
  104. }
  105. type SurgeScriptOptions struct {
  106. CronOptions *CronScriptOptions `json:"cron,omitempty"`
  107. }
  108. type CronScriptOptions struct {
  109. Expression string `json:"expression"`
  110. Arguments []string `json:"arguments,omitempty"`
  111. Timeout badoption.Duration `json:"timeout,omitempty"`
  112. }