Skip to content

Commit

Permalink
Use protovalidate constraints when generating scalar values
Browse files Browse the repository at this point in the history
  • Loading branch information
sudorandom committed Aug 17, 2024
1 parent 740871e commit bf4eb5c
Show file tree
Hide file tree
Showing 15 changed files with 619 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
46 changes: 46 additions & 0 deletions gen_bytes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package fauxrpc

import (
"buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
"github.com/brianvoe/gofakeit/v7"
)

type BytesHints struct {
Rules *validate.BytesRules
FirstName bool
LastName bool
Name bool
UUID bool
URL bool
Version bool
}

func GenerateBytes(faker *gofakeit.Faker, hints BytesHints) []byte {
if hints.Rules == nil {
return []byte(faker.HipsterSentence(3))
}

if hints.Rules.Const != nil {
return hints.Rules.Const
}
minLen, maxLen := uint64(0), uint64(20)
if hints.Rules.Len != nil {
minLen = *hints.Rules.Len
maxLen = *hints.Rules.Len
}
if hints.Rules.MinLen != nil {
minLen = *hints.Rules.MinLen
}
if hints.Rules.MaxLen != nil {
maxLen = *hints.Rules.MaxLen
}
if hints.Rules.Pattern != nil {
return []byte(faker.Regex(*hints.Rules.Pattern))
}

if len(hints.Rules.In) > 0 {
return hints.Rules.In[faker.IntRange(0, len(hints.Rules.In)-1)]
}

return []byte(faker.Sentence(int(maxLen / uint64(4)))[minLen:maxLen])
}
47 changes: 32 additions & 15 deletions gen_fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ func (g *dataGenerator) getFieldValue(field protoreflect.FieldDescriptor, st sta
case protoreflect.MessageKind:
switch string(field.Message().FullName()) {
case "google.protobuf.Duration":
// TODO: hints
return g.genGoogleDuration()
case "google.protobuf.Timestamp":
// TODO: hints
return g.genGoogleTimestamp()
case "google.protobuf.Any":
// TODO: hints
return nil
case "google.protobuf.Value":
// TODO: hints
return g.genGoogleValue()
default:
nested := dynamicpb.NewMessage(field.Message())
Expand Down Expand Up @@ -63,44 +67,57 @@ func (g *dataGenerator) getFieldValue(field protoreflect.FieldDescriptor, st sta
}
v := protoreflect.ValueOfString(GenerateString(g.faker, hints))
return &v
case protoreflect.BytesKind:
hints := BytesHints{Rules: constraints.GetBytes()}
v := protoreflect.ValueOfBytes(GenerateBytes(g.faker, hints))
return &v
case protoreflect.Int32Kind:
v := protoreflect.ValueOfInt32(g.faker.Int32())
hints := Int32Hints{Rules: constraints.GetInt32()}
v := protoreflect.ValueOfInt32(GenerateInt32(g.faker, hints))
return &v
case protoreflect.Sint32Kind:
v := protoreflect.ValueOfInt32(g.faker.Int32())
hints := SInt32Hints{Rules: constraints.GetSint32()}
v := protoreflect.ValueOfInt32(GenerateSInt32(g.faker, hints))
return &v
case protoreflect.Sfixed32Kind:
v := protoreflect.ValueOfInt32(g.faker.Int32())
hints := SFixedInt32Hints{Rules: constraints.GetSfixed32()}
v := protoreflect.ValueOfInt32(GenerateSFixedInt32(g.faker, hints))
return &v
case protoreflect.Uint32Kind:
v := protoreflect.ValueOfUint32(g.faker.Uint32())
hints := UInt32Hints{Rules: constraints.GetUint32()}
v := protoreflect.ValueOfUint32(GenerateUInt32(g.faker, hints))
return &v
case protoreflect.Fixed32Kind:
v := protoreflect.ValueOfUint32(g.faker.Uint32())
hints := Fixed32Hints{Rules: constraints.GetFixed32()}
v := protoreflect.ValueOfUint32(GenerateFixed32(g.faker, hints))
return &v
case protoreflect.Int64Kind:
v := protoreflect.ValueOfInt64(g.faker.Int64())
hints := Int64Hints{Rules: constraints.GetInt64()}
v := protoreflect.ValueOfInt64(GenerateInt64(g.faker, hints))
return &v
case protoreflect.Sint64Kind:
v := protoreflect.ValueOfInt64(g.faker.Int64())
hints := SInt64Hints{Rules: constraints.GetSint64()}
v := protoreflect.ValueOfInt64(GenerateSInt64(g.faker, hints))
return &v
case protoreflect.Sfixed64Kind:
v := protoreflect.ValueOfInt64(g.faker.Int64())
hints := SFixed64Hints{Rules: constraints.GetSfixed64()}
v := protoreflect.ValueOfInt64(GenerateSFixed64(g.faker, hints))
return &v
case protoreflect.Uint64Kind:
v := protoreflect.ValueOfUint64(g.faker.Uint64())
hints := UInt64Hints{Rules: constraints.GetUint64()}
v := protoreflect.ValueOfUint64(GenerateUInt64(g.faker, hints))
return &v
case protoreflect.Fixed64Kind:
v := protoreflect.ValueOfUint64(g.faker.Uint64())
hints := Fixed64Hints{Rules: constraints.GetFixed64()}
v := protoreflect.ValueOfUint64(GenerateFixed64(g.faker, hints))
return &v
case protoreflect.FloatKind:
v := protoreflect.ValueOfFloat32(g.faker.Float32())
hints := Float32Hints{Rules: constraints.GetFloat()}
v := protoreflect.ValueOfFloat32(GenerateFloat32(g.faker, hints))
return &v
case protoreflect.DoubleKind:
v := protoreflect.ValueOfFloat64(g.faker.Float64())
return &v
case protoreflect.BytesKind:
v := protoreflect.ValueOfBytes([]byte(g.faker.LoremIpsumSentence(10)))
hints := Float64Hints{Rules: constraints.GetDouble()}
v := protoreflect.ValueOfFloat64(GenerateFloat64(g.faker, hints))
return &v
default:
return nil
Expand Down
45 changes: 45 additions & 0 deletions gen_fixed32.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package fauxrpc

import (
"math"

"buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
"github.com/brianvoe/gofakeit/v7"
)

type Fixed32Hints struct {
Rules *validate.Fixed32Rules
}

func GenerateFixed32(faker *gofakeit.Faker, hints Fixed32Hints) uint32 {
if hints.Rules == nil {
return faker.Uint32()
}

if hints.Rules.Const != nil {
return *hints.Rules.Const
}
minVal, maxVal := uint32(0), uint32(math.MaxInt32)
if hints.Rules.GreaterThan != nil {
switch v := hints.Rules.GreaterThan.(type) {
case *validate.Fixed32Rules_Gt:
minVal = v.Gt + 1
case *validate.Fixed32Rules_Gte:
minVal = v.Gte
}
}
if hints.Rules.LessThan != nil {
switch v := hints.Rules.LessThan.(type) {
case *validate.Fixed32Rules_Lt:
maxVal = v.Lt + 1
case *validate.Fixed32Rules_Lte:
maxVal = v.Lte
}
}

if len(hints.Rules.In) > 0 {
return hints.Rules.In[faker.IntRange(0, len(hints.Rules.In)-1)]
}

return uint32(faker.IntRange(int(minVal), int(maxVal)))
}
45 changes: 45 additions & 0 deletions gen_fixedint64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package fauxrpc

import (
"math"

"buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
"github.com/brianvoe/gofakeit/v7"
)

type Fixed64Hints struct {
Rules *validate.Fixed64Rules
}

func GenerateFixed64(faker *gofakeit.Faker, hints Fixed64Hints) uint64 {
if hints.Rules == nil {
return faker.Uint64()
}

if hints.Rules.Const != nil {
return *hints.Rules.Const
}
minVal, maxVal := uint64(0), uint64(math.MaxInt64)
if hints.Rules.GreaterThan != nil {
switch v := hints.Rules.GreaterThan.(type) {
case *validate.Fixed64Rules_Gt:
minVal = v.Gt + 1
case *validate.Fixed64Rules_Gte:
minVal = v.Gte
}
}
if hints.Rules.LessThan != nil {
switch v := hints.Rules.LessThan.(type) {
case *validate.Fixed64Rules_Lt:
maxVal = v.Lt + 1
case *validate.Fixed64Rules_Lte:
maxVal = v.Lte
}
}

if len(hints.Rules.In) > 0 {
return hints.Rules.In[faker.IntRange(0, len(hints.Rules.In)-1)]
}

return uint64(faker.UintRange(uint(minVal), uint(maxVal)))
}
45 changes: 45 additions & 0 deletions gen_float32.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package fauxrpc

import (
"math"

"buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
"github.com/brianvoe/gofakeit/v7"
)

type Float32Hints struct {
Rules *validate.FloatRules
}

func GenerateFloat32(faker *gofakeit.Faker, hints Float32Hints) float32 {
if hints.Rules == nil {
return faker.Float32()
}

if hints.Rules.Const != nil {
return *hints.Rules.Const
}
minVal, maxVal := float32(0), float32(math.MaxFloat32)
if hints.Rules.GreaterThan != nil {
switch v := hints.Rules.GreaterThan.(type) {
case *validate.FloatRules_Gt:
minVal = v.Gt + 1
case *validate.FloatRules_Gte:
minVal = v.Gte
}
}
if hints.Rules.LessThan != nil {
switch v := hints.Rules.LessThan.(type) {
case *validate.FloatRules_Lt:
maxVal = v.Lt + 1
case *validate.FloatRules_Lte:
maxVal = v.Lte
}
}

if len(hints.Rules.In) > 0 {
return hints.Rules.In[faker.IntRange(0, len(hints.Rules.In)-1)]
}

return faker.Float32Range(minVal, maxVal)
}
45 changes: 45 additions & 0 deletions gen_float64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package fauxrpc

import (
"math"

"buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
"github.com/brianvoe/gofakeit/v7"
)

type Float64Hints struct {
Rules *validate.DoubleRules
}

func GenerateFloat64(faker *gofakeit.Faker, hints Float64Hints) float64 {
if hints.Rules == nil {
return faker.Float64()
}

if hints.Rules.Const != nil {
return *hints.Rules.Const
}
minVal, maxVal := float64(0), float64(math.MaxFloat64)
if hints.Rules.GreaterThan != nil {
switch v := hints.Rules.GreaterThan.(type) {
case *validate.DoubleRules_Gt:
minVal = v.Gt + 1
case *validate.DoubleRules_Gte:
minVal = v.Gte
}
}
if hints.Rules.LessThan != nil {
switch v := hints.Rules.LessThan.(type) {
case *validate.DoubleRules_Lt:
maxVal = v.Lt + 1
case *validate.DoubleRules_Lte:
maxVal = v.Lte
}
}

if len(hints.Rules.In) > 0 {
return hints.Rules.In[faker.IntRange(0, len(hints.Rules.In)-1)]
}

return faker.Float64Range(minVal, maxVal)
}
45 changes: 45 additions & 0 deletions gen_int32.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package fauxrpc

import (
"math"

"buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
"github.com/brianvoe/gofakeit/v7"
)

type Int32Hints struct {
Rules *validate.Int32Rules
}

func GenerateInt32(faker *gofakeit.Faker, hints Int32Hints) int32 {
if hints.Rules == nil {
return faker.Int32()
}

if hints.Rules.Const != nil {
return *hints.Rules.Const
}
minVal, maxVal := int32(0), int32(math.MaxInt32)
if hints.Rules.GreaterThan != nil {
switch v := hints.Rules.GreaterThan.(type) {
case *validate.Int32Rules_Gt:
minVal = v.Gt + 1
case *validate.Int32Rules_Gte:
minVal = v.Gte
}
}
if hints.Rules.LessThan != nil {
switch v := hints.Rules.LessThan.(type) {
case *validate.Int32Rules_Lt:
maxVal = v.Lt + 1
case *validate.Int32Rules_Lte:
maxVal = v.Lte
}
}

if len(hints.Rules.In) > 0 {
return hints.Rules.In[faker.IntRange(0, len(hints.Rules.In)-1)]
}

return int32(faker.IntRange(int(minVal), int(maxVal)))
}
Loading

0 comments on commit bf4eb5c

Please sign in to comment.