| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- package option
- import (
- "context"
- E "github.com/sagernet/sing/common/exceptions"
- "github.com/sagernet/sing/common/json"
- "github.com/sagernet/sing/common/json/badjson"
- "github.com/sagernet/sing/service"
- )
- type CertificateProviderOptionsRegistry interface {
- CreateOptions(providerType string) (any, bool)
- }
- type _CertificateProvider struct {
- Type string `json:"type"`
- Tag string `json:"tag,omitempty"`
- Options any `json:"-"`
- }
- type CertificateProvider _CertificateProvider
- func (h *CertificateProvider) MarshalJSONContext(ctx context.Context) ([]byte, error) {
- return badjson.MarshallObjectsContext(ctx, (*_CertificateProvider)(h), h.Options)
- }
- func (h *CertificateProvider) UnmarshalJSONContext(ctx context.Context, content []byte) error {
- err := json.UnmarshalContext(ctx, content, (*_CertificateProvider)(h))
- if err != nil {
- return err
- }
- registry := service.FromContext[CertificateProviderOptionsRegistry](ctx)
- if registry == nil {
- return E.New("missing certificate provider options registry in context")
- }
- options, loaded := registry.CreateOptions(h.Type)
- if !loaded {
- return E.New("unknown certificate provider type: ", h.Type)
- }
- err = badjson.UnmarshallExcludedContext(ctx, content, (*_CertificateProvider)(h), options)
- if err != nil {
- return err
- }
- h.Options = options
- return nil
- }
- type CertificateProviderOptions struct {
- Tag string `json:"-"`
- Type string `json:"-"`
- Options any `json:"-"`
- }
- type _CertificateProviderInline struct {
- Type string `json:"type"`
- }
- func (o *CertificateProviderOptions) MarshalJSONContext(ctx context.Context) ([]byte, error) {
- if o.Tag != "" {
- return json.Marshal(o.Tag)
- }
- return badjson.MarshallObjectsContext(ctx, _CertificateProviderInline{Type: o.Type}, o.Options)
- }
- func (o *CertificateProviderOptions) UnmarshalJSONContext(ctx context.Context, content []byte) error {
- if len(content) == 0 {
- return E.New("empty certificate_provider value")
- }
- if content[0] == '"' {
- return json.UnmarshalContext(ctx, content, &o.Tag)
- }
- var inline _CertificateProviderInline
- err := json.UnmarshalContext(ctx, content, &inline)
- if err != nil {
- return err
- }
- o.Type = inline.Type
- if o.Type == "" {
- return E.New("missing certificate provider type")
- }
- registry := service.FromContext[CertificateProviderOptionsRegistry](ctx)
- if registry == nil {
- return E.New("missing certificate provider options registry in context")
- }
- options, loaded := registry.CreateOptions(o.Type)
- if !loaded {
- return E.New("unknown certificate provider type: ", o.Type)
- }
- err = badjson.UnmarshallExcludedContext(ctx, content, &inline, options)
- if err != nil {
- return err
- }
- o.Options = options
- return nil
- }
- func (o *CertificateProviderOptions) IsShared() bool {
- return o.Tag != ""
- }
|