package option import ( E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json/badoption" ) type OnDemandOptions struct { Enabled bool `json:"enabled,omitempty"` Rules []OnDemandRule `json:"rules,omitempty"` } type OnDemandRule struct { Action *OnDemandRuleAction `json:"action,omitempty"` DNSSearchDomainMatch badoption.Listable[string] `json:"dns_search_domain_match,omitempty"` DNSServerAddressMatch badoption.Listable[string] `json:"dns_server_address_match,omitempty"` InterfaceTypeMatch *OnDemandRuleInterfaceType `json:"interface_type_match,omitempty"` SSIDMatch badoption.Listable[string] `json:"ssid_match,omitempty"` ProbeURL string `json:"probe_url,omitempty"` } type OnDemandRuleAction int func (r *OnDemandRuleAction) MarshalJSON() ([]byte, error) { if r == nil { return nil, nil } value := *r var actionName string switch value { case 1: actionName = "connect" case 2: actionName = "disconnect" case 3: actionName = "evaluate_connection" default: return nil, E.New("unknown action: ", value) } return json.Marshal(actionName) } func (r *OnDemandRuleAction) UnmarshalJSON(bytes []byte) error { var actionName string if err := json.Unmarshal(bytes, &actionName); err != nil { return err } var actionValue int switch actionName { case "connect": actionValue = 1 case "disconnect": actionValue = 2 case "evaluate_connection": actionValue = 3 case "ignore": actionValue = 4 default: return E.New("unknown action name: ", actionName) } *r = OnDemandRuleAction(actionValue) return nil } type OnDemandRuleInterfaceType int func (r *OnDemandRuleInterfaceType) MarshalJSON() ([]byte, error) { if r == nil { return nil, nil } value := *r var interfaceTypeName string switch value { case 1: interfaceTypeName = "any" case 2: interfaceTypeName = "wifi" case 3: interfaceTypeName = "cellular" default: return nil, E.New("unknown interface type: ", value) } return json.Marshal(interfaceTypeName) } func (r *OnDemandRuleInterfaceType) UnmarshalJSON(bytes []byte) error { var interfaceTypeName string if err := json.Unmarshal(bytes, &interfaceTypeName); err != nil { return err } var interfaceTypeValue int switch interfaceTypeName { case "any": interfaceTypeValue = 1 case "wifi": interfaceTypeValue = 2 case "cellular": interfaceTypeValue = 3 default: return E.New("unknown interface type name: ", interfaceTypeName) } *r = OnDemandRuleInterfaceType(interfaceTypeValue) return nil }