pkg net/url, method (*URL) AppendBinary([]uint8) ([]uint8, error) #62384
pkg log/slog, method (Level) AppendText([]uint8) ([]uint8, error) #62384
pkg log/slog, method (*LevelVar) AppendText([]uint8) ([]uint8, error) #62384
+pkg math/big, method (*Float) AppendText([]uint8) ([]uint8, error) #62384
+pkg math/big, method (*Int) AppendText([]uint8) ([]uint8, error) #62384
+pkg math/big, method (*Rat) AppendText([]uint8) ([]uint8, error) #62384
+pkg regexp, method (*Regexp) AppendText([]uint8) ([]uint8, error) #62384
--- /dev/null
+[Float], [Int] and [Rat] now implement the [encoding.TextAppender] interface.
--- /dev/null
+[Regexp] now implements the [encoding.TextAppender] interface.
return nil
}
-// MarshalText implements the [encoding.TextMarshaler] interface.
+// AppendText implements the [encoding.TextAppender] interface.
// Only the [Float] value is marshaled (in full precision), other
// attributes such as precision or accuracy are ignored.
-func (x *Float) MarshalText() (text []byte, err error) {
+func (x *Float) AppendText(b []byte) ([]byte, error) {
if x == nil {
- return []byte("<nil>"), nil
+ return append(b, "<nil>"...), nil
}
- var buf []byte
- return x.Append(buf, 'g', -1), nil
+ return x.Append(b, 'g', -1), nil
+}
+
+// MarshalText implements the [encoding.TextMarshaler] interface.
+// Only the [Float] value is marshaled (in full precision), other
+// attributes such as precision or accuracy are ignored.
+func (x *Float) MarshalText() (text []byte, err error) {
+ return x.AppendText(nil)
}
// UnmarshalText implements the [encoding.TextUnmarshaler] interface.
}
}
}
+
+func TestFloatAppendText(t *testing.T) {
+ for _, test := range floatVals {
+ for _, sign := range []string{"", "+", "-"} {
+ for _, prec := range []uint{0, 1, 2, 10, 53, 64, 100, 1000} {
+ if prec > 53 && testing.Short() {
+ continue
+ }
+ x := sign + test
+ var tx Float
+ _, _, err := tx.SetPrec(prec).Parse(x, 0)
+ if err != nil {
+ t.Errorf("parsing of %s (prec = %d) failed (invalid test case): %v", x, prec, err)
+ continue
+ }
+ buf := make([]byte, 4, 32)
+ b, err := tx.AppendText(buf)
+ if err != nil {
+ t.Errorf("marshaling of %v (prec = %d) failed: %v", &tx, prec, err)
+ continue
+ }
+ var rx Float
+ rx.SetPrec(prec)
+ if err := rx.UnmarshalText(b[4:]); err != nil {
+ t.Errorf("unmarshaling of %v (prec = %d) failed: %v", &tx, prec, err)
+ continue
+ }
+ if rx.Cmp(&tx) != 0 {
+ t.Errorf("AppendText of %v (prec = %d) failed: got %v want %v", &tx, prec, &rx, &tx)
+ }
+ }
+ }
+ }
+}
+
+func TestFloatAppendTextNil(t *testing.T) {
+ var x *Float
+ buf := make([]byte, 4, 16)
+ data, _ := x.AppendText(buf)
+ if string(data[4:]) != "<nil>" {
+ t.Errorf("got %q, want <nil>", data[4:])
+ }
+}
return nil
}
+// AppendText implements the [encoding.TextAppender] interface.
+func (x *Int) AppendText(b []byte) (text []byte, err error) {
+ return x.Append(b, 10), nil
+}
+
// MarshalText implements the [encoding.TextMarshaler] interface.
func (x *Int) MarshalText() (text []byte, err error) {
- if x == nil {
- return []byte("<nil>"), nil
- }
- return x.abs.itoa(x.neg, 10), nil
+ return x.AppendText(nil)
}
// UnmarshalText implements the [encoding.TextUnmarshaler] interface.
}
}
}
+
+func TestIntAppendText(t *testing.T) {
+ for _, test := range encodingTests {
+ for _, sign := range []string{"", "+", "-"} {
+ x := sign + test
+ var tx Int
+ tx.SetString(x, 10)
+ buf := make([]byte, 4, 32)
+ b, err := tx.AppendText(buf)
+ if err != nil {
+ t.Errorf("marshaling of %s failed: %s", &tx, err)
+ continue
+ }
+ var rx Int
+ if err := rx.UnmarshalText(b[4:]); err != nil {
+ t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+ continue
+ }
+ if rx.Cmp(&tx) != 0 {
+ t.Errorf("AppendText of %s failed: got %s want %s", &tx, &rx, &tx)
+ }
+ }
+ }
+}
+
+func TestIntAppendTextNil(t *testing.T) {
+ var x *Int
+ buf := make([]byte, 4, 16)
+ data, _ := x.AppendText(buf)
+ if string(data[4:]) != "<nil>" {
+ t.Errorf("got %q, want <nil>", data[4:])
+ }
+}
// String returns a string representation of x in the form "a/b" (even if b == 1).
func (x *Rat) String() string {
- return string(x.marshal())
+ return string(x.marshal(nil))
}
-// marshal implements String returning a slice of bytes
-func (x *Rat) marshal() []byte {
- var buf []byte
+// marshal implements [Rat.String] returning a slice of bytes.
+// It appends the string representation of x in the form "a/b" (even if b == 1) to buf,
+// and returns the extended buffer.
+func (x *Rat) marshal(buf []byte) []byte {
buf = x.a.Append(buf, 10)
buf = append(buf, '/')
if len(x.b.abs) != 0 {
return nil
}
-// MarshalText implements the [encoding.TextMarshaler] interface.
-func (x *Rat) MarshalText() (text []byte, err error) {
+// AppendText implements the [encoding.TextAppender] interface.
+func (x *Rat) AppendText(b []byte) ([]byte, error) {
if x.IsInt() {
- return x.a.MarshalText()
+ return x.a.AppendText(b)
}
- return x.marshal(), nil
+ return x.marshal(b), nil
+}
+
+// MarshalText implements the [encoding.TextMarshaler] interface.
+func (x *Rat) MarshalText() (text []byte, err error) {
+ return x.AppendText(nil)
}
// UnmarshalText implements the [encoding.TextUnmarshaler] interface.
}
}
}
+
+func TestRatAppendText(t *testing.T) {
+ for _, num := range ratNums {
+ for _, denom := range ratDenoms {
+ var tx Rat
+ tx.SetString(num + "/" + denom)
+ buf := make([]byte, 4, 32)
+ b, err := tx.AppendText(buf)
+ if err != nil {
+ t.Errorf("marshaling of %s failed: %s", &tx, err)
+ continue
+ }
+ var rx Rat
+ if err := rx.UnmarshalText(b[4:]); err != nil {
+ t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+ continue
+ }
+ if rx.Cmp(&tx) != 0 {
+ t.Errorf("AppendText of %s failed: got %s want %s", &tx, &rx, &tx)
+ }
+ }
+ }
+}
if unmarshaled.String() != goodRe[i] {
t.Errorf("UnmarshalText returned unexpected value: %s", unmarshaled.String())
}
+
+ buf := make([]byte, 4, 32)
+ marshalAppend, err := re.AppendText(buf)
+ if err != nil {
+ t.Errorf("regexp %#q failed to marshal: %s", re, err)
+ continue
+ }
+ marshalAppend = marshalAppend[4:]
+ if err := unmarshaled.UnmarshalText(marshalAppend); err != nil {
+ t.Errorf("regexp %#q failed to unmarshal: %s", re, err)
+ continue
+ }
+ if unmarshaled.String() != goodRe[i] {
+ t.Errorf("UnmarshalText returned unexpected value: %s", unmarshaled.String())
+ }
}
t.Run("invalid pattern", func(t *testing.T) {
re := new(Regexp)
return strings
}
-// MarshalText implements [encoding.TextMarshaler]. The output
+// AppendText implements [encoding.TextAppender]. The output
// matches that of calling the [Regexp.String] method.
//
// Note that the output is lossy in some cases: This method does not indicate
// POSIX regular expressions (i.e. those compiled by calling [CompilePOSIX]), or
// those for which the [Regexp.Longest] method has been called.
+func (re *Regexp) AppendText(b []byte) ([]byte, error) {
+ return append(b, re.String()...), nil
+}
+
+// MarshalText implements [encoding.TextMarshaler]. The output
+// matches that of calling the [Regexp.AppendText] method.
+//
+// See [Regexp.AppendText] for more information.
func (re *Regexp) MarshalText() ([]byte, error) {
- return []byte(re.String()), nil
+ return re.AppendText(nil)
}
// UnmarshalText implements [encoding.TextUnmarshaler] by calling