♻️ Add tools.WriteValue

This commit is contained in:
Dan Jones 2024-03-03 13:56:48 -06:00
commit 286ac4557d
4 changed files with 97 additions and 31 deletions

View file

@ -2,12 +2,9 @@ package models
import ( import (
"bytes" "bytes"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"regexp" "regexp"
"strconv"
"time"
"codeberg.org/danjones000/my-log/tools" "codeberg.org/danjones000/my-log/tools"
) )
@ -25,33 +22,9 @@ func (m Meta) MarshalText() ([]byte, error) {
buff.WriteRune('@') buff.WriteRune('@')
buff.WriteString(m.Key) buff.WriteString(m.Key)
buff.WriteRune(' ') buff.WriteRune(' ')
switch v := m.Value.(type) { n, err := tools.WriteValue(buff, m.Value)
default: if n == 0 || err != nil {
return nil, fmt.Errorf("Unknown type %T", v) return []byte{}, err
case nil:
return []byte{}, nil
case string:
buff.WriteString(v)
case int:
buff.WriteString(strconv.Itoa(v))
case int64:
buff.WriteString(strconv.FormatInt(v, 10))
case float64:
buff.WriteString(strconv.FormatFloat(v, 'f', -1, 64))
case json.Number:
buff.WriteString(v.String())
case json.RawMessage:
buff.Write(v)
case []byte:
buff.Write(v)
case byte:
buff.WriteByte(v)
case rune:
buff.WriteString(string(v))
case bool:
buff.WriteString(strconv.FormatBool(v))
case time.Time:
buff.WriteString(v.Format(time.RFC3339))
} }
return buff.Bytes(), nil return buff.Bytes(), nil

View file

@ -40,7 +40,7 @@ func TestMeta(t *testing.T) {
{"byte", "byteme", byte(67), "@byteme C", nil, "C"}, {"byte", "byteme", byte(67), "@byteme C", nil, "C"},
{"json-obj", "obj", json.RawMessage(`{"foo":"bar","baz":"quux"}`), `@obj {"foo":"bar","baz":"quux"}`, nil, json.RawMessage(`{"foo":"bar","baz":"quux"}`)}, {"json-obj", "obj", json.RawMessage(`{"foo":"bar","baz":"quux"}`), `@obj {"foo":"bar","baz":"quux"}`, nil, json.RawMessage(`{"foo":"bar","baz":"quux"}`)},
{"json-arr", "arr", json.RawMessage(`["foo",42,"bar", null,"quux", true]`), `@arr ["foo",42,"bar", null,"quux", true]`, nil, json.RawMessage(`["foo",42,"bar", null,"quux", true]`)}, {"json-arr", "arr", json.RawMessage(`["foo",42,"bar", null,"quux", true]`), `@arr ["foo",42,"bar", null,"quux", true]`, nil, json.RawMessage(`["foo",42,"bar", null,"quux", true]`)},
{"chan", "nope", make(chan bool), "", errors.New("Unknown type chan bool"), ""}, {"chan", "nope", make(chan bool), "", errors.New("Unsupported type chan bool"), ""},
{"whitespace-key", "no space", "hi", "", errors.New("whitespace is not allowed in key: no space"), ""}, {"whitespace-key", "no space", "hi", "", errors.New("whitespace is not allowed in key: no space"), ""},
{"empty-mar", "nope", skipMarshalTest, "", nil, ErrorParsing}, {"empty-mar", "nope", skipMarshalTest, "", nil, ErrorParsing},
{"no-key-mar", "nope", skipMarshalTest, "nope", nil, ErrorParsing}, {"no-key-mar", "nope", skipMarshalTest, "nope", nil, ErrorParsing},

44
tools/write_buffer.go Normal file
View file

@ -0,0 +1,44 @@
package tools
import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"time"
)
func WriteValue(buff *bytes.Buffer, val any) (n int, err error) {
switch v := val.(type) {
default:
err = fmt.Errorf("Unsupported type %T", v)
case nil:
return
case string:
return buff.WriteString(v)
case int:
return buff.WriteString(strconv.Itoa(v))
case int64:
return buff.WriteString(strconv.FormatInt(v, 10))
case float64:
return buff.WriteString(strconv.FormatFloat(v, 'f', -1, 64))
case json.Number:
return buff.WriteString(v.String())
case json.RawMessage:
return buff.Write(v)
case []byte:
return buff.Write(v)
case byte:
err = buff.WriteByte(v)
if err == nil {
n = 1
}
case rune:
return buff.WriteString(string(v))
case bool:
return buff.WriteString(strconv.FormatBool(v))
case time.Time:
return buff.WriteString(v.Format(time.RFC3339))
}
return
}

View file

@ -0,0 +1,49 @@
package tools
import (
"bytes"
"encoding/json"
"errors"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestWriteBuffer(t *testing.T) {
when := time.Now()
tests := []struct {
name string
value any
out string
err error
}{
{"nil", nil, "", nil},
{"string", "hi", "hi", nil},
{"bytes", []byte{104, 105}, "hi", nil},
{"byte", byte(104), "h", nil},
{"rune", 'h', "h", nil},
{"int", 42, "42", nil},
{"int64", int64(42), "42", nil},
{"float", 42.13, "42.13", nil},
{"bool", false, "false", nil},
{"json.Number", json.Number("42.13"), "42.13", nil},
{"json.RawMessage", json.RawMessage("{}"), "{}", nil},
{"time", when, when.Format(time.RFC3339), nil},
{"struct", struct{}{}, "", errors.New("Unsupported type struct {}")},
}
for _, tt := range tests {
t.Run(tt.name, getWriteTestRunner(tt.value, tt.out, tt.err))
}
}
func getWriteTestRunner(value any, out string, err error) func(*testing.T) {
return func(t *testing.T) {
buff := &bytes.Buffer{}
n, er := WriteValue(buff, value)
assert.Equal(t, len(out), n)
assert.Equal(t, err, er)
assert.Equal(t, out, buff.String())
}
}