summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-10 15:27:46 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-10 21:48:22 -0700
commit04daa09e1911d7bdabe87e452200b2de2c5ca7c9 (patch)
tree4e125b226bec6c9ec33335c4d9ff3bdfd874242c
parent1f0abce0bf4061261572f6ed2f815f71647cc7e5 (diff)
Be more careful about importing encoding/json
-rw-r--r--ReleaseNotes.md10
-rw-r--r--common.go16
-rw-r--r--decode.go15
-rw-r--r--encode.go9
-rw-r--r--external.go48
5 files changed, 62 insertions, 36 deletions
diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index d1b5693..9974f0e 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -1,3 +1,13 @@
+# v0.3.6 (TBD)
+
+ Theme: TBD
+
+ User-facing changes:
+
+ - `Number` and `RawMessage` type aliases are now available, so that
+ a user of lowmemjson's native APIs does not need to import
+ `encoding/json` or compat/json in order to use them.
+
# v0.3.5 (2023-02-10)
Theme: Compatibility bugfixes
diff --git a/common.go b/common.go
deleted file mode 100644
index 90156b9..0000000
--- a/common.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com>
-//
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-package lowmemjson
-
-import (
- "encoding/json"
- "reflect"
-)
-
-var (
- numberType = reflect.TypeOf(json.Number(""))
- byteType = reflect.TypeOf(byte(0))
- byteSliceType = reflect.TypeOf(([]byte)(nil))
-)
diff --git a/decode.go b/decode.go
index 1b6bdf2..645f8de 100644
--- a/decode.go
+++ b/decode.go
@@ -14,7 +14,6 @@ package lowmemjson
import (
"bytes"
"encoding"
- "encoding/json"
"fmt"
"io"
"reflect"
@@ -357,14 +356,6 @@ func (dec *Decoder) limitingScanner() io.RuneScanner {
// decoder main ////////////////////////////////////////////////////////////////////////////////////
-var (
- rawMessagePtrType = reflect.TypeOf((*json.RawMessage)(nil))
- decodableType = reflect.TypeOf((*Decodable)(nil)).Elem()
- jsonUnmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
- textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
- float64Type = reflect.TypeOf(float64(0))
-)
-
var kind2bits = map[reflect.Kind]int{
reflect.Int: int(32 << (^uint(0) >> 63)),
reflect.Int8: 8,
@@ -393,7 +384,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
t := dec.peekRuneType()
var buf bytes.Buffer
dec.scan(&buf)
- if err := val.Addr().Interface().(*json.RawMessage).UnmarshalJSON(buf.Bytes()); err != nil {
+ if err := val.Addr().Interface().(*RawMessage).UnmarshalJSON(buf.Bytes()); err != nil {
dec.panicType(t.JSONType(), reflect.PointerTo(typ), err)
}
case val.CanAddr() && reflect.PointerTo(typ).Implements(decodableType):
@@ -410,7 +401,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) {
t := dec.peekRuneType()
var buf bytes.Buffer
dec.scan(&buf)
- obj := val.Addr().Interface().(json.Unmarshaler)
+ obj := val.Addr().Interface().(jsonUnmarshaler)
if err := obj.UnmarshalJSON(buf.Bytes()); err != nil {
dec.panicType(t.JSONType(), reflect.PointerTo(typ), err)
}
@@ -826,7 +817,7 @@ func (dec *Decoder) decodeAny() any {
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
var buf strings.Builder
dec.scan(&buf)
- num := json.Number(buf.String())
+ num := Number(buf.String())
if dec.useNumber {
return num
}
diff --git a/encode.go b/encode.go
index 492b40f..b6541cd 100644
--- a/encode.go
+++ b/encode.go
@@ -8,7 +8,6 @@ import (
"bytes"
"encoding"
"encoding/base64"
- "encoding/json"
"fmt"
"io"
"reflect"
@@ -96,12 +95,6 @@ func discardInt(_ int, err error) error {
return err
}
-var (
- encodableType = reflect.TypeOf((*Encodable)(nil)).Elem()
- jsonMarshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
- textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
-)
-
const startDetectingCyclesAfter = 1000
func encode(w *ReEncoder, val reflect.Value, escaper BackslashEscaper, quote bool, cycleDepth uint, cycleSeen map[any]struct{}) error {
@@ -145,7 +138,7 @@ func encode(w *ReEncoder, val reflect.Value, escaper BackslashEscaper, quote boo
if val.Kind() == reflect.Pointer && val.IsNil() {
return discardInt(w.WriteString("null"))
}
- obj, ok := val.Interface().(json.Marshaler)
+ obj, ok := val.Interface().(jsonMarshaler)
if !ok {
return discardInt(w.WriteString("null"))
}
diff --git a/external.go b/external.go
new file mode 100644
index 0000000..c8a1f68
--- /dev/null
+++ b/external.go
@@ -0,0 +1,48 @@
+// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com>
+//
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package lowmemjson
+
+import (
+ "encoding"
+ "encoding/json"
+ "reflect"
+)
+
+// A Number represents a JSON number value. It is represented as a
+// string containing the raw JSON text; it is useful for preserving
+// number values with perfect fidelity, but isn't so useful for use as
+// a number value in a Go program.
+type Number = json.Number
+
+// A RawMessage is a raw encoded JSON value. This saves time when
+// encoding or decoding, but does mean that the full text must be
+// buffered when decoding.
+type RawMessage = json.RawMessage
+
+type (
+ jsonMarshaler = json.Marshaler
+ jsonUnmarshaler = json.Unmarshaler
+)
+
+var (
+ // common types.
+ numberType = reflect.TypeOf(Number(""))
+ byteType = reflect.TypeOf(byte(0))
+ byteSliceType = reflect.TypeOf(([]byte)(nil))
+
+ // encodable/marshaler types.
+ encodableType = reflect.TypeOf((*Encodable)(nil)).Elem()
+ jsonMarshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
+ textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
+
+ // decodable/unmarshaler types.
+ decodableType = reflect.TypeOf((*Decodable)(nil)).Elem()
+ jsonUnmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
+ textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+
+ // other types used by Decoder.
+ rawMessagePtrType = reflect.TypeOf((*json.RawMessage)(nil))
+ float64Type = reflect.TypeOf(float64(0))
+)