Skip to content

Commit 536d8ff

Browse files
committed
feat: implemented protoJSON decoder caching
1 parent 06b4908 commit 536d8ff

File tree

2 files changed

+47
-12
lines changed

2 files changed

+47
-12
lines changed

decoder/protojson/decoder.go

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"google.golang.org/protobuf/encoding/protojson"
77

88
gojsondecoder "github.com/ralvarezdev/go-json/decoder"
9+
goreflect "github.com/ralvarezdev/go-reflect"
910
)
1011

1112
type (
@@ -71,28 +72,28 @@ func NewDecoder(options *Options) *Decoder {
7172
//
7273
// Parameters:
7374
//
74-
// - body: The body to decode
75+
// - reader: The body to decode
7576
// - dest: The destination to store the decoded body
7677
//
7778
// Returns:
7879
//
7980
// - error: The error if any
8081
func (d Decoder) Decode(
81-
body any,
82+
reader any,
8283
dest any,
8384
) error {
84-
// Check the body
85-
if body == nil {
86-
return gojsondecoder.ErrNilBody
85+
// Check the reader
86+
if reader == nil {
87+
return ErrNilReader
8788
}
8889

89-
// Check the body type
90-
reader, err := gojsondecoder.ToReader(body)
90+
// Check the reader type
91+
parsedReader, err := gojsondecoder.ToReader(reader)
9192
if err != nil {
9293
return err
9394
}
9495

95-
return d.DecodeReader(reader, dest)
96+
return d.DecodeReader(parsedReader, dest)
9697
}
9798

9899
// DecodeReader decodes a JSON body from a reader into a destination
@@ -119,14 +120,47 @@ func (d Decoder) DecodeReader(
119120
return gojsondecoder.ErrNilDestination
120121
}
121122

122-
// Read all data from the reader
123-
data, err := io.ReadAll(reader)
123+
// Read all body from the reader
124+
body, err := io.ReadAll(reader)
124125
if err != nil {
125126
return err
126127
}
128+
129+
// Check if the cache is enabled and use cached mapper if available
130+
if d.cache && d.cachedMappers != nil {
131+
// Get the unique type identifier for the destination
132+
uniqueTypeReference := goreflect.UniqueTypeReference(dest)
133+
134+
// Check if there is a cached mapper for the destination type
135+
if mapper, found := d.cachedMappers[uniqueTypeReference]; found {
136+
return mapper.UnmarshalByReflection(
137+
body,
138+
dest,
139+
&d.unmarshalOptions,
140+
)
141+
}
142+
}
143+
144+
// Initialize the cache map if caching is enabled
145+
if d.cache && d.cachedMappers == nil {
146+
d.cachedMappers = make(map[string]*Mapper)
147+
}
148+
149+
// Create a new mapper for the destination type
150+
mapper, err := NewMapper(dest)
151+
if err != nil {
152+
return err
153+
}
127154

128-
return UnmarshalByReflection(
129-
data,
155+
// Store the mapper in the cache if caching is enabled
156+
if d.cache {
157+
uniqueTypeReference := goreflect.UniqueTypeReference(dest)
158+
d.cachedMappers[uniqueTypeReference] = mapper
159+
}
160+
161+
// Unmarshal the body into the destination using the mapper
162+
return mapper.UnmarshalByReflection(
163+
body,
130164
dest,
131165
&d.unmarshalOptions,
132166
)

decoder/protojson/errors.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const (
99
)
1010

1111
var (
12+
ErrNilReader = errors.New("nil reader")
1213
ErrNilMapper = errors.New("decoder mapper is nil")
1314
ErrNilDestinationInstance = errors.New("nil destination instance")
1415
ErrNilDestination = errors.New("nil destination")

0 commit comments

Comments
 (0)