summaryrefslogtreecommitdiff
path: root/encode.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@datawire.io>2022-08-17 15:19:12 -0600
committerLuke Shumaker <lukeshu@datawire.io>2022-08-17 15:43:38 -0600
commit494ad195bc31ce6a65f759544355801fe357c56d (patch)
treed7c8b5d59626651a446614666ee02f6a3044e439 /encode.go
parent25f5b3a2aabe11a7f8dad3d001ac30b65c1e6c06 (diff)
Add more tests around trailing-newlines from the encoder
Diffstat (limited to 'encode.go')
-rw-r--r--encode.go42
1 files changed, 33 insertions, 9 deletions
diff --git a/encode.go b/encode.go
index a77d8aa..44fd985 100644
--- a/encode.go
+++ b/encode.go
@@ -40,8 +40,25 @@ func encodeWriteString(w io.Writer, str string) {
}
type Encoder struct {
- W io.Writer
- BackslashEscape BackslashEscaper
+ w *ReEncoder
+}
+
+// NewEncoder returns a new encoder.
+//
+// If w is an *ReEncoder, then the inner backslash-escaping of
+// double-encoded ",string" tagged string values obeys the
+// *ReEncoder's BackslashEscape policy.
+func NewEncoder(w io.Writer) *Encoder {
+ re, ok := w.(*ReEncoder)
+ if !ok {
+ re = &ReEncoder{
+ Out: w,
+ AllowMultipleValues: true,
+ }
+ }
+ return &Encoder{
+ w: re,
+ }
}
func (enc *Encoder) Encode(obj any) (err error) {
@@ -54,16 +71,21 @@ func (enc *Encoder) Encode(obj any) (err error) {
}
}
}()
- encode(enc.W, reflect.ValueOf(obj), enc.BackslashEscape, false, 0, map[any]struct{}{})
- if f, ok := enc.W.(interface{ Flush() error }); ok {
- return f.Flush()
- }
- return nil
+ encode(enc.w, reflect.ValueOf(obj), enc.w.BackslashEscape, false, 0, map[any]struct{}{})
+ return enc.w.Close()
}
+// Encode encodes a value to w.
+//
+// If w is an *ReEncoder, then the inner backslash-escaping of
+// double-encoded ",string" tagged string values obeys the
+// *ReEncoder's BackslashEscape policy.
+//
+// Does not write a trailing newline or other whitespace; if you will
+// be encoding multiple values to w, then you should instead use an
+// *Encoder object, as some JSON values need whitespace between them.
func Encode(w io.Writer, obj any) (err error) {
- enc := &Encoder{W: w}
- return enc.Encode(obj)
+ return NewEncoder(w).Encode(obj)
}
var (
@@ -94,6 +116,7 @@ func encode(w io.Writer, val reflect.Value, escaper BackslashEscaper, quote bool
encodeWriteString(w, "null")
return
}
+ // Use a sub-ReEncoder to check that it's a full element.
validator := &ReEncoder{Out: w, BackslashEscape: escaper}
if err := obj.EncodeJSON(validator); err != nil {
panic(encodeError{&EncodeMethodError{
@@ -127,6 +150,7 @@ func encode(w io.Writer, val reflect.Value, escaper BackslashEscaper, quote bool
SourceFunc: "MarshalJSON",
}})
}
+ // Use a sub-ReEncoder to check that it's a full element.
validator := &ReEncoder{Out: w, BackslashEscape: escaper}
if _, err := validator.Write(dat); err != nil {
panic(encodeError{err})