✨ Add Meta with TextMarshaler
This commit is contained in:
		
					parent
					
						
							
								c61c783c66
							
						
					
				
			
			
				commit
				
					
						3cfb1ccedb
					
				
			
		
					 2 changed files with 106 additions and 0 deletions
				
			
		|  | @ -1 +1,53 @@ | ||||||
| package models | package models | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"regexp" | ||||||
|  | 	"strconv" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type Meta struct { | ||||||
|  | 	Key   string | ||||||
|  | 	Value any | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (m Meta) MarshalText() ([]byte, error) { | ||||||
|  | 	if regexp.MustCompile(`\s`).MatchString(m.Key) { | ||||||
|  | 		return []byte{}, fmt.Errorf("whitespace is now allowed in key: %s", m.Key) | ||||||
|  | 	} | ||||||
|  | 	buff := &bytes.Buffer{} | ||||||
|  | 	buff.WriteRune('@') | ||||||
|  | 	buff.WriteString(m.Key) | ||||||
|  | 	buff.WriteRune(' ') | ||||||
|  | 	switch v := m.Value.(type) { | ||||||
|  | 	default: | ||||||
|  | 		return nil, fmt.Errorf("Unknown type %T", v) | ||||||
|  | 	case nil: | ||||||
|  | 		return []byte{}, nil | ||||||
|  | 	case string: | ||||||
|  | 		buff.WriteString(v) | ||||||
|  | 	case int: | ||||||
|  | 		buff.WriteString(strconv.Itoa(v)) | ||||||
|  | 	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 | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										54
									
								
								models/meta_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								models/meta_test.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | ||||||
|  | package models | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"errors" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Type assertions | ||||||
|  | var _ encoding.TextMarshaler = Meta{} | ||||||
|  | 
 | ||||||
|  | func TestMeta(t *testing.T) { | ||||||
|  | 	when := time.Now() | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name  string | ||||||
|  | 		key   string | ||||||
|  | 		value any | ||||||
|  | 		out   string | ||||||
|  | 		err   error | ||||||
|  | 	}{ | ||||||
|  | 		{"int", "num", 42, "@num 42", nil}, | ||||||
|  | 		{"float", "num", 42.13, "@num 42.13", nil}, | ||||||
|  | 		{"string", "word", "hello", "@word hello", nil}, | ||||||
|  | 		{"json number", "num", json.Number("42.13"), "@num 42.13", nil}, | ||||||
|  | 		{"true", "b", true, "@b true", nil}, | ||||||
|  | 		{"false", "b", false, "@b false", nil}, | ||||||
|  | 		{"nil", "n", nil, "", nil}, | ||||||
|  | 		{"time", "when", when, "@when " + when.Format(time.RFC3339), nil}, | ||||||
|  | 		{"rune", "char", '@', "@char @", nil}, | ||||||
|  | 		{"bytes", "byteme", []byte("yo"), "@byteme yo", nil}, | ||||||
|  | 		{"byte", "byteme", byte(67), "@byteme C", nil}, | ||||||
|  | 		{"json-obj", "obj", json.RawMessage(`{"foo":"bar","baz":"quux"}`), `@obj {"foo":"bar","baz":"quux"}`, nil}, | ||||||
|  | 		{"json-arr", "arr", json.RawMessage(`["foo",42,"bar", null,"quux", true]`), `@arr ["foo",42,"bar", null,"quux", true]`, nil}, | ||||||
|  | 		{"chan", "nope", make(chan bool), "", errors.New("Unknown type chan bool")}, | ||||||
|  | 		{"whitespace", "no space", "hi", "", errors.New("whitespace is now allowed in key: no space")}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, tt := range tests { | ||||||
|  | 		t.Run(tt.name, getMetaTestRunner(tt.key, tt.value, tt.out, tt.err)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getMetaTestRunner(key string, value any, out string, err error) func(*testing.T) { | ||||||
|  | 	return func(t *testing.T) { | ||||||
|  | 		st := Meta{key, value} | ||||||
|  | 		o, e := st.MarshalText() | ||||||
|  | 		assert.Equal(t, out, string(o)) | ||||||
|  | 		assert.Equal(t, err, e) | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue