diff --git a/ngo/codec/serializer_json.go b/ngo/codec/serializer_json.go deleted file mode 100644 index 69f63e7..0000000 --- a/ngo/codec/serializer_json.go +++ /dev/null @@ -1,25 +0,0 @@ -package codec - -import ( - "encoding/json" - "git.noahlan.cn/noahlan/ntool/ndef" -) - -type JsonSerializer struct { -} - -func NewJsonSerializer() ndef.Serializer { - return &JsonSerializer{} -} - -func (s *JsonSerializer) Marshal(v interface{}) ([]byte, error) { - marshal, err := json.Marshal(v) - if err != nil { - return nil, err - } - return marshal, nil -} - -func (s *JsonSerializer) Unmarshal(data []byte, v interface{}) error { - return json.Unmarshal(data, v) -} diff --git a/njson/json.go b/njson/json.go new file mode 100644 index 0000000..67d93d8 --- /dev/null +++ b/njson/json.go @@ -0,0 +1,75 @@ +package njson + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "strings" +) + +// Marshal marshals v into json bytes. +// see json.Marshal +func Marshal(v any) ([]byte, error) { + return json.Marshal(v) +} + +// MarshalStr marshals v into a string. +func MarshalStr(v any) (string, error) { + data, err := Marshal(v) + if err != nil { + return "", err + } + return string(data), nil +} + +// MarshalStrSafe marshals v into a string. +// return an empty string if an error occurred. +func MarshalStrSafe(v any) string { + ret, _ := MarshalStr(v) + return ret +} + +// Unmarshal data bytes into v. +func Unmarshal(data []byte, v any) error { + decoder := json.NewDecoder(bytes.NewReader(data)) + if err := unmarshalUseNumber(decoder, v); err != nil { + return formatError(string(data), err) + } + + return nil +} + +// UnmarshalFromStr unmarshal v from str. +func UnmarshalFromStr(str string, v any) error { + decoder := json.NewDecoder(strings.NewReader(str)) + if err := unmarshalUseNumber(decoder, v); err != nil { + return formatError(str, err) + } + + return nil +} + +// UnmarshalFromReader unmarshal v from reader. +func UnmarshalFromReader(reader io.Reader, v any) error { + var buf strings.Builder + teeReader := io.TeeReader(reader, &buf) + decoder := json.NewDecoder(teeReader) + if err := unmarshalUseNumber(decoder, v); err != nil { + return formatError(buf.String(), err) + } + + return nil +} + +// unmarshalUseNumber 避免出现科学计算,如1e+100 +// 这是由于默认 unmarshal 时会将大于6位的数值类型使用 float64 解析 +// 同时也可以避免精度丢失 double -> float64 等 +func unmarshalUseNumber(decoder *json.Decoder, v any) error { + decoder.UseNumber() + return decoder.Decode(v) +} + +func formatError(v string, err error) error { + return fmt.Errorf("string: `%s`, error: `%w`", v, err) +} diff --git a/njson/serializer.go b/njson/serializer.go new file mode 100644 index 0000000..23e3c55 --- /dev/null +++ b/njson/serializer.go @@ -0,0 +1,24 @@ +package njson + +import ( + "git.noahlan.cn/noahlan/ntool/ndef" +) + +type JsonSerializer struct { +} + +func NewJsonSerializer() ndef.Serializer { + return &JsonSerializer{} +} + +func (s *JsonSerializer) Marshal(v any) ([]byte, error) { + marshal, err := Marshal(v) + if err != nil { + return nil, err + } + return marshal, nil +} + +func (s *JsonSerializer) Unmarshal(data []byte, v any) error { + return Unmarshal(data, v) +}