Ordered json output & Disallow unknown fields

This commit is contained in:
世界
2022-07-03 11:28:15 +08:00
parent 85a695caa1
commit ef5cfd59d4
16 changed files with 243 additions and 26 deletions

View File

@@ -1,8 +1,9 @@
package option
import (
"encoding/json"
"net/netip"
"github.com/goccy/go-json"
)
type ListenAddress netip.Addr

View File

@@ -1,14 +1,27 @@
package option
import "github.com/sagernet/sing/common"
import (
"bytes"
type Options struct {
"github.com/goccy/go-json"
"github.com/sagernet/sing/common"
)
type _Options struct {
Log *LogOption `json:"log,omitempty"`
Inbounds []Inbound `json:"inbounds,omitempty"`
Outbounds []Outbound `json:"outbounds,omitempty"`
Route *RouteOptions `json:"route,omitempty"`
}
type Options _Options
func (o *Options) UnmarshalJSON(content []byte) error {
decoder := json.NewDecoder(bytes.NewReader(content))
decoder.DisallowUnknownFields()
return decoder.Decode((*_Options)(o))
}
func (o Options) Equals(other Options) bool {
return common.ComparablePtrEquals(o.Log, other.Log) &&
common.SliceEquals(o.Inbounds, other.Inbounds) &&

View File

@@ -1,8 +1,7 @@
package option
import (
"encoding/json"
"github.com/goccy/go-json"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/auth"
E "github.com/sagernet/sing/common/exceptions"
@@ -69,7 +68,11 @@ func (h *Inbound) UnmarshalJSON(bytes []byte) error {
default:
return nil
}
return json.Unmarshal(bytes, v)
err = UnmarshallExcluded(bytes, (*_Inbound)(h), v)
if err != nil {
return E.Cause(err, "inbound options")
}
return nil
}
type ListenOptions struct {

View File

@@ -1,18 +1,19 @@
package option
import (
"encoding/json"
"bytes"
"github.com/sagernet/sing/common/x/linkedhashmap"
"github.com/goccy/go-json"
"github.com/sagernet/sing-box/common/linkedhashmap"
)
func ToMap(v any) (*linkedhashmap.Map[string, any], error) {
bytes, err := json.Marshal(v)
inputContent, err := json.Marshal(v)
if err != nil {
return nil, err
}
var content linkedhashmap.Map[string, any]
err = json.Unmarshal(bytes, &content)
err = content.UnmarshalJSON(inputContent)
if err != nil {
return nil, err
}
@@ -36,5 +37,25 @@ func MarshallObjects(objects ...any) ([]byte, error) {
if err != nil {
return nil, err
}
return json.Marshal(content)
return content.MarshalJSON()
}
func UnmarshallExcluded(inputContent []byte, parentObject any, object any) error {
parentContent, err := ToMap(parentObject)
if err != nil {
return err
}
var content linkedhashmap.Map[string, any]
err = content.UnmarshalJSON(inputContent)
if err != nil {
return err
}
content.RemoveAll(parentContent.Keys())
inputContent, err = content.MarshalJSON()
if err != nil {
return err
}
decoder := json.NewDecoder(bytes.NewReader(inputContent))
decoder.DisallowUnknownFields()
return decoder.Decode(object)
}

View File

@@ -1,6 +1,6 @@
package option
import "encoding/json"
import "github.com/goccy/go-json"
type Listable[T comparable] []T

View File

@@ -1,8 +1,7 @@
package option
import (
"encoding/json"
"github.com/goccy/go-json"
C "github.com/sagernet/sing-box/constant"
E "github.com/sagernet/sing/common/exceptions"
)

View File

@@ -1,8 +1,7 @@
package option
import (
"encoding/json"
"github.com/goccy/go-json"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
)
@@ -43,7 +42,11 @@ func (h *Outbound) UnmarshalJSON(bytes []byte) error {
default:
return nil
}
return json.Unmarshal(bytes, v)
err = UnmarshallExcluded(bytes, (*_Outbound)(h), v)
if err != nil {
return E.Cause(err, "outbound options")
}
return nil
}
type DialerOptions struct {

View File

@@ -1,8 +1,7 @@
package option
import (
"encoding/json"
"github.com/goccy/go-json"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
@@ -68,7 +67,11 @@ func (r *Rule) UnmarshalJSON(bytes []byte) error {
default:
return E.New("unknown rule type: " + r.Type)
}
return json.Unmarshal(bytes, v)
err = UnmarshallExcluded(bytes, (*_Rule)(r), v)
if err != nil {
return E.Cause(err, "route rule")
}
return nil
}
type DefaultRule struct {