Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

moretypes #27

Merged
merged 5 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions codec/encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ import (

"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/dynamicpb"
"google.golang.org/protobuf/types/known/timestamppb"

"github.com/pentops/jsonapi/j5types/date_j5t"
"github.com/pentops/jsonapi/prototest"
"github.com/pentops/jsonapi/testproto/gen/testpb"
)

Expand Down Expand Up @@ -207,6 +211,94 @@ func TestUnmarshal(t *testing.T) {
}
}

func TestScalars(t *testing.T) {
// TODO: The tests above should be rewritten to use this method, then retire
// testproto.

type testCase struct {
desc protoreflect.MessageDescriptor
asJSON string
valMap map[string]protoreflect.Value
}

runTest := func(t testing.TB, tc testCase) {

msgIn := dynamicpb.NewMessage(tc.desc)

for key, val := range tc.valMap {
field := tc.desc.Fields().ByName(protoreflect.Name(key))
if field == nil {
t.Fatalf("field %s not found", key)
}
msgIn.Set(field, val)
}

asJSON, err := Encode(Options{}, msgIn.ProtoReflect())
if err != nil {
t.Fatal(err)
}

CompareJSON(t, []byte(tc.asJSON), asJSON)

msgOut := dynamicpb.NewMessage(tc.desc)
if err := Decode(Options{}, []byte(tc.asJSON), msgOut.ProtoReflect()); err != nil {
t.Fatal(err)
}

if !proto.Equal(msgIn, msgOut) {
t.Fatalf("proto equal, expected %s but got %s", msgIn, msgOut)
}

}

t.Run("string", func(t *testing.T) {
runTest(t, testCase{
desc: prototest.SingleMessage(t, "string sString = 1;"),
asJSON: `{"sString":"val"}`,
valMap: map[string]protoreflect.Value{
"sString": protoreflect.ValueOfString("val"),
},
})
})

t.Run("optional string", func(t *testing.T) {
msg := prototest.SingleMessage(t, "optional string foo = 1;")

runTest(t, testCase{
desc: msg,
asJSON: `{"foo":"val"}`,
valMap: map[string]protoreflect.Value{
"foo": protoreflect.ValueOfString("val"),
},
})

runTest(t, testCase{
desc: msg,
asJSON: `{}`,
valMap: map[string]protoreflect.Value{},
})
})

t.Run("date", func(t *testing.T) {
msg := prototest.SingleMessage(t,
prototest.WithMessageImports("j5/types/date/v1/date.proto"),
"j5.types.date.v1.Date date = 1;")
dateVal := &date_j5t.Date{
Year: 2020,
Month: 12,
Day: 30,
}
runTest(t, testCase{
desc: msg,
asJSON: `{"date":"2020-12-30"}`,
valMap: map[string]protoreflect.Value{
"date": protoreflect.ValueOfMessage(dateVal.ProtoReflect()),
},
})
})

}

func CompareJSON(t testing.TB, wantSRC, gotSRC []byte) {
t.Helper()
wantBuff := &bytes.Buffer{}
Expand Down
78 changes: 76 additions & 2 deletions codec/wkt.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package codec
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"time"

"google.golang.org/protobuf/reflect/protoreflect"
Expand All @@ -29,14 +31,19 @@ const (
WKTBytes = "BytesValue"

WKTEmpty = "Empty"

JTDate = protoreflect.FullName("j5.types.date.v1.Date")
JTDecimal = protoreflect.FullName("j5.types.decimal.v1.Decimal")
)

type marshalFunc func(*encoder, protoreflect.Message) error

type unmarshalFunc func(*decoder, protoreflect.Message) error

// wellKnownTypeMarshaler returns a marshal function if the message type
// has specialized serialization behavior. It returns nil otherwise.
// has specialized serialization behavior, either by the official spec, or j5
// types.
// It returns nil otherwise.
func wellKnownTypeMarshaler(name protoreflect.FullName) marshalFunc {
if name.Parent() == WKTProtoNamespace {
switch name.Name() {
Expand All @@ -61,11 +68,20 @@ func wellKnownTypeMarshaler(name protoreflect.FullName) marshalFunc {
return marshalEmpty
}
}

switch name {
case JTDate:
return marshalDate
case JTDecimal:
return marshalWrapperType
}
return nil
}

// wellKnownTypeUnmarshaler returns a unmarshal function if the message type
// has specialized serialization behavior. It returns nil otherwise.
// has specialized serialization behavior, either by the official spec, or j5
// types.
// It returns nil otherwise.
func wellKnownTypeUnmarshaler(name protoreflect.FullName) unmarshalFunc {
if name.Parent() == WKTProtoNamespace {
switch name.Name() {
Expand All @@ -90,6 +106,14 @@ func wellKnownTypeUnmarshaler(name protoreflect.FullName) unmarshalFunc {
return unmarshalEmpty
}
}

switch name {
case JTDate:
return unmarshalDate
case JTDecimal:
return unmarshalWrapperType
}

return nil
}

Expand Down Expand Up @@ -159,3 +183,53 @@ func marshalWrapperType(e *encoder, msg protoreflect.Message) error {
val := msg.Get(fd)
return e.encodeValue(fd, val)
}

func unmarshalDate(d *decoder, msg protoreflect.Message) error {
tok, err := d.Token()
if err != nil {
return err
}

stringVal, ok := tok.(string)
if !ok {
return fmt.Errorf("expected date as a string but got %v", tok)
}

stringParts := strings.Split(stringVal, "-")
if len(stringParts) != 3 {
return fmt.Errorf("expected date as a string but got %v", tok)
}

for idx, key := range []protoreflect.Name{"year", "month", "day"} {
field := msg.Descriptor().Fields().ByName(key)
if field == nil {
return fmt.Errorf("field %s not found", key)
}

intVal, err := strconv.ParseInt(stringParts[idx], 10, 32)
if err != nil {
return fmt.Errorf("expected date as yyyy-mm-dd, got %s", stringVal)
}

msg.Set(field, protoreflect.ValueOf(int32(intVal)))
}

return nil
}

func marshalDate(e *encoder, msg protoreflect.Message) error {

intParts := make([]int32, 3)
for idx, key := range []protoreflect.Name{"year", "month", "day"} {
field := msg.Descriptor().Fields().ByName(key)
if field == nil {
return fmt.Errorf("field %s not found", key)
}

val := msg.Get(field).Int()
intParts[idx] = int32(val)
}

stringVal := fmt.Sprintf("%04d-%02d-%02d", intParts[0], intParts[1], intParts[2])
return e.addJSON(stringVal)
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ require (
github.com/bufbuild/protoyaml-go v0.1.6
github.com/go-yaml/yaml v2.1.0+incompatible
github.com/google/uuid v1.4.0
github.com/gorilla/mux v1.8.1
github.com/jhump/protoreflect v1.15.3
github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1
github.com/pentops/log.go v0.0.0-20231218074934-67aedcab3fa4
github.com/pentops/o5-go v0.0.0-20240108212127-807bf5c29410
github.com/pentops/o5-runtime-sidecar v0.0.6
github.com/pentops/runner v0.0.0-20231219070819-c4878d5565d8
github.com/pentops/sugar-go v0.0.0-20231029194349-ec12ec0132c5
github.com/shopspring/decimal v1.3.1
github.com/stretchr/testify v1.8.4
github.com/tidwall/gjson v1.17.0
google.golang.org/genproto/googleapis/api v0.0.0-20231127180814-3a041ad873d4
Expand Down Expand Up @@ -47,8 +49,6 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/cel-go v0.18.2 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/pentops/log.go v0.0.0-20231218074934-67aedcab3fa4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -605,8 +605,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1 h1:dOYG7LS/WK00RWZc8XGgcUTlTxpp3mKhdR2Q9z9HbXM=
github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8=
github.com/pentops/log.go v0.0.0-20231218074934-67aedcab3fa4 h1:7kPDmBAQxMxcFIYt1rEco/AipZmm1CUoND3wSDmIOeI=
github.com/pentops/log.go v0.0.0-20231218074934-67aedcab3fa4/go.mod h1:UXhrs+VZ6cWZ7b/v8AtuvBZc5nwS5WFHP94JoFrZQA8=
github.com/pentops/o5-go v0.0.0-20240108212127-807bf5c29410 h1:modR3GqNo1R0crr5HR9sY5YwIj8zpCcBGsc6mGAiVJY=
Expand All @@ -627,6 +625,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
Expand Down
2 changes: 1 addition & 1 deletion gogen/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"regexp"
"strings"

"github.com/pentops/jsonapi/gen/j5/v1/schema_j5pb"
"github.com/pentops/jsonapi/gen/j5/schema/v1/schema_j5pb"
)

type Options struct {
Expand Down
2 changes: 1 addition & 1 deletion gogen/gen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"go/token"
"testing"

"github.com/pentops/jsonapi/gen/j5/schema/v1/schema_j5pb"
"github.com/pentops/jsonapi/gen/j5/source/v1/source_j5pb"
"github.com/pentops/jsonapi/gen/j5/v1/schema_j5pb"
"github.com/pentops/jsonapi/structure"
"github.com/pentops/jsonapi/testproto/gen/testpb"
"github.com/stretchr/testify/assert"
Expand Down
Loading
Loading