endpoint.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. package option
  2. import (
  3. "context"
  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/service"
  8. )
  9. type EndpointOptionsRegistry interface {
  10. CreateOptions(endpointType string) (any, bool)
  11. }
  12. type _Endpoint struct {
  13. Type string `json:"type"`
  14. Tag string `json:"tag,omitempty"`
  15. Options any `json:"-"`
  16. }
  17. type Endpoint _Endpoint
  18. func (h *Endpoint) MarshalJSONContext(ctx context.Context) ([]byte, error) {
  19. return badjson.MarshallObjectsContext(ctx, (*_Endpoint)(h), h.Options)
  20. }
  21. func (h *Endpoint) UnmarshalJSONContext(ctx context.Context, content []byte) error {
  22. err := json.UnmarshalContext(ctx, content, (*_Endpoint)(h))
  23. if err != nil {
  24. return err
  25. }
  26. registry := service.FromContext[EndpointOptionsRegistry](ctx)
  27. if registry == nil {
  28. return E.New("missing endpoint fields registry in context")
  29. }
  30. options, loaded := registry.CreateOptions(h.Type)
  31. if !loaded {
  32. return E.New("unknown endpoint type: ", h.Type)
  33. }
  34. err = badjson.UnmarshallExcludedContext(ctx, content, (*_Endpoint)(h), options)
  35. if err != nil {
  36. return err
  37. }
  38. h.Options = options
  39. return nil
  40. }