summaryrefslogtreecommitdiffhomepage
path: root/cmd/fastjson/testcodegen
diff options
context:
space:
mode:
authorAndrew Dunham <andrew@du.nham.ca>2023-03-13 14:07:07 -0400
committerAndrew Dunham <andrew@du.nham.ca>2023-03-13 14:56:38 -0400
commitb080e6bb2d520c09a93a83302cd3d94363163862 (patch)
tree654c4b319971a1ecf17b851e34c881286b3c8212 /cmd/fastjson/testcodegen
parent223713d4a1fc79a5c4f61d3655b173f7cb1e2409 (diff)
downloadtailscale-andrew/fastjson.tar.xz
tailscale-andrew/fastjson.zip
Change-Id: I5295d47102d879f29f0a6818481e8b65eafd02dd
Diffstat (limited to 'cmd/fastjson/testcodegen')
-rw-r--r--cmd/fastjson/testcodegen/gen_test.go71
-rw-r--r--cmd/fastjson/testcodegen/json_gen.go141
-rw-r--r--cmd/fastjson/testcodegen/ping_request.go69
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
+}