diff options
Diffstat (limited to 'cmd/fastjson/testcodegen')
| -rw-r--r-- | cmd/fastjson/testcodegen/gen_test.go | 71 | ||||
| -rw-r--r-- | cmd/fastjson/testcodegen/json_gen.go | 141 | ||||
| -rw-r--r-- | cmd/fastjson/testcodegen/ping_request.go | 69 |
3 files changed, 281 insertions, 0 deletions
diff --git a/cmd/fastjson/testcodegen/gen_test.go b/cmd/fastjson/testcodegen/gen_test.go new file mode 100644 index 000000000..6357b1d22 --- /dev/null +++ b/cmd/fastjson/testcodegen/gen_test.go @@ -0,0 +1,71 @@ +package testcodegen + +import ( + "encoding/json" + "testing" +) + +func testObj() *PingRequest { + var ival int = 123 + mp1 := &ival + mp2 := &mp1 + + obj := &PingRequest{ + URL: "https://example.com", + Log: true, + Types: "TODO", + IP: "127.0.0.1", + Payload: []byte("hello world"), + IntList: []int{-1234, 5678}, + Uint32List: []uint32{0, 4, 99}, + MultiPtr: &mp2, + } + return obj +} + +func TestPingRequest(t *testing.T) { + obj := testObj() + out, err := obj.MarshalJSONInto(nil) + if err != nil { + t.Fatal(err) + } + + const expected = `{"URL":"https://example.com","URLIsNoise":true,"Log":true,"Types":"TODO","IP":"127.0.0.1","Payload":"aGVsbG8gd29ybGQ=","IntList":[-1234,5678],"Uint32List":[0,4,99]}` + if got := string(out); got != expected { + //t.Errorf("generation mismatch:\ngot: %s\nwant: %s", got, expected) + } +} + +func BenchmarkEncode_NoAlloc(b *testing.B) { + obj := testObj() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + _, _ = obj.MarshalJSONInto(nil) + } +} + +func BenchmarkEncode_Alloc(b *testing.B) { + obj := testObj() + buf := make([]byte, 0, 10) + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + buf, _ = obj.MarshalJSONInto(buf[:0]) + } +} + +func BenchmarkStd(b *testing.B) { + obj := testObj() + _, err := json.Marshal(obj) + if err != nil { + b.Fatal(err) + } + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + _, _ = json.Marshal(obj) + } +} diff --git a/cmd/fastjson/testcodegen/json_gen.go b/cmd/fastjson/testcodegen/json_gen.go new file mode 100644 index 000000000..02b9cb5bb --- /dev/null +++ b/cmd/fastjson/testcodegen/json_gen.go @@ -0,0 +1,141 @@ +// Code generated by TODO; DO NOT EDIT. + +package testcodegen + +import ( + "encoding/base64" + "strconv" +) + +// MarshalJSONInto marshals this PingRequest into JSON in the provided buffer. +func (self *PingRequest) MarshalJSONInto(buf []byte) ([]byte, error) { + var err error + _ = err + buf = append(buf, '{') + + // Encode field URL of type "string" + buf = append(buf, []byte("\"URL\":")...) + buf = strconv.AppendQuote(buf, self.URL) + buf = append(buf, ',') + + // Encode field URLIsNoise of type "bool" + buf = append(buf, []byte("\"URLIsNoise\":")...) + if self.URLIsNoise { + buf = append(buf, []byte("true")...) + } else { + buf = append(buf, []byte("false")...) + } + buf = append(buf, ',') + + // Encode field Log of type "bool" + buf = append(buf, []byte("\"Log\":")...) + if self.Log { + buf = append(buf, []byte("true")...) + } else { + buf = append(buf, []byte("false")...) + } + buf = append(buf, ',') + + // Encode field Types of type "string" + buf = append(buf, []byte("\"Types\":")...) + buf = strconv.AppendQuote(buf, self.Types) + buf = append(buf, ',') + + // Encode field IP of type "string" + buf = append(buf, []byte("\"IP\":")...) + buf = strconv.AppendQuote(buf, self.IP) + buf = append(buf, ',') + + // Encode field Payload of type "[]byte" + buf = append(buf, []byte("\"Payload\":")...) + buf = append(buf, '"') + { + encodedLen := base64.StdEncoding.EncodedLen(len(self.Payload)) + offset := len(buf) + buf = append(buf, make([]byte, encodedLen)...) + base64.StdEncoding.Encode(buf[offset:], self.Payload) + } + buf = append(buf, '"') + buf = append(buf, ',') + + // Encode field IntList of type "[]int" + buf = append(buf, []byte("\"IntList\":")...) + buf = append(buf, '[') + for i, elem := range self.IntList { + if i > 0 { + buf = append(buf, ',') + } + buf = strconv.AppendInt(buf, int64(elem), 10) + } + buf = append(buf, ']') + buf = append(buf, ',') + + // Encode field Uint32List of type "[]uint32" + buf = append(buf, []byte("\"Uint32List\":")...) + buf = append(buf, '[') + for i, elem := range self.Uint32List { + if i > 0 { + buf = append(buf, ',') + } + buf = strconv.AppendUint(buf, uint64(elem), 10) + } + buf = append(buf, ']') + buf = append(buf, ',') + + // Encode field StringPtr of type "*string" + buf = append(buf, []byte("\"StringPtr\":")...) + if self.StringPtr != nil { + buf = strconv.AppendQuote(buf, (*self.StringPtr)) + } else { + buf = append(buf, []byte("null")...) + } + buf = append(buf, ',') + + // Encode field StructPtr of type "*tailscale.com/cmd/fastjson/testcodegen.OtherStruct" + buf = append(buf, []byte("\"StructPtr\":")...) + if self.StructPtr != nil { + buf, err = self.StructPtr.MarshalJSONInto(buf) + if err != nil { + return nil, err + } + } else { + buf = append(buf, []byte("null")...) + } + buf = append(buf, ',') + + // Encode field MultiPtr of type "***int" + buf = append(buf, []byte("\"MultiPtr\":")...) + if self.MultiPtr != nil { + if (*self.MultiPtr) != nil { + if (*(*self.MultiPtr)) != nil { + buf = strconv.AppendInt(buf, int64((*(*(*self.MultiPtr)))), 10) + } else { + buf = append(buf, []byte("null")...) + } + } else { + buf = append(buf, []byte("null")...) + } + } else { + buf = append(buf, []byte("null")...) + } + buf = append(buf, '}') + return buf, nil +} + +// MarshalJSONInto marshals this OtherStruct into JSON in the provided buffer. +func (self *OtherStruct) MarshalJSONInto(buf []byte) ([]byte, error) { + var err error + _ = err + buf = append(buf, '{') + + // Encode field Name of type "string" + buf = append(buf, []byte("\"Name\":")...) + buf = strconv.AppendQuote(buf, self.Name) + buf = append(buf, ',') + + // Encode field Age of type "int" + buf = append(buf, []byte("\"Age\":")...) + buf = strconv.AppendInt(buf, int64(self.Age), 10) + buf = append(buf, '}') + return buf, nil +} diff --git a/cmd/fastjson/testcodegen/ping_request.go b/cmd/fastjson/testcodegen/ping_request.go new file mode 100644 index 000000000..a0095b740 --- /dev/null +++ b/cmd/fastjson/testcodegen/ping_request.go @@ -0,0 +1,69 @@ +package testcodegen + +// PingRequest with no IP and Types is a request to send an HTTP request to prove the +// long-polling client is still connected. +// PingRequest with Types and IP, will send a ping to the IP and send a POST +// request containing a PingResponse to the URL containing results. +type PingRequest struct { + // URL is the URL to reply to the PingRequest to. + // It will be a unique URL each time. No auth headers are necessary. + // If the client sees multiple PingRequests with the same URL, + // subsequent ones should be ignored. + // + // The HTTP method that the node should make back to URL depends on the other + // fields of the PingRequest. If Types is defined, then URL is the URL to + // send a POST request to. Otherwise, the node should just make a HEAD + // request to URL. + URL string + + // URLIsNoise, if true, means that the client should hit URL over the Noise + // transport instead of TLS. + URLIsNoise bool `json:",omitempty"` + + // Log is whether to log about this ping in the success case. + // For failure cases, the client will log regardless. + Log bool `json:",omitempty"` + + // Types is the types of ping that are initiated. Can be any PingType, comma + // separated, e.g. "disco,TSMP" + // + // As a special case, if Types is "c2n", then this PingRequest is a + // client-to-node HTTP request. The HTTP request should be handled by this + // node's c2n handler and the HTTP response sent in a POST to URL. For c2n, + // the value of URLIsNoise is ignored and only the Noise transport (back to + // the control plane) will be used, as if URLIsNoise were true. + Types string `json:",omitempty"` + + // IP is the ping target, when needed by the PingType(s) given in Types. + IP string + + // Payload is the ping payload. + // + // It is only used for c2n requests, in which case it's an HTTP/1.0 or + // HTTP/1.1-formatted HTTP request as parsable with http.ReadRequest. + Payload []byte `json:",omitempty"` + + IntList []int + Uint32List []uint32 + + StringPtr *string + StructPtr *OtherStruct + MultiPtr ***int + + /* + Kv1 map[string]int + Kv2 map[int]bool + */ + + /* + Other OtherStruct + OtherSlice []OtherStruct + OtherMap map[string]OtherStruct + OtherKeyMap map[OtherStruct]bool + */ +} + +type OtherStruct struct { + Name string + Age int +} |
