33package lduser
44
55import (
6- "gopkg.in/launchdarkly/go-jsonstream.v1/jreader"
76 "gopkg.in/launchdarkly/go-jsonstream.v1/jwriter"
7+ "gopkg.in/launchdarkly/go-sdk-common.v2/ldvalue"
88
99 "github.com/mailru/easyjson/jlexer"
1010 ej_jwriter "github.com/mailru/easyjson/jwriter"
@@ -17,8 +17,10 @@ import (
1717// encoding/json, and will call them if present. But this mechanism is inefficient: when marshaling
1818// it requires the allocation of intermediate byte slices, and when unmarshaling it causes the
1919// JSON object to be parsed twice. It is preferable to have our marshal/unmarshal methods write to
20- // and read from the EasyJSON Writer/Lexer directly. Our go-jsonstream library provides methods for
21- // doing this, if the launchdarkly_easyjson build tag is set.package ldmodel
20+ // and read from the EasyJSON Writer/Lexer directly. Also, since user deserialization is a
21+ // high-traffic path in some LaunchDarkly code on the service side, the extra overhead of the
22+ // go-jsonstream abstraction is undesirable and we'll instead use an EasyJSON-generated
23+ // deserializer for an intermediate struct type.
2224//
2325// For more information, see: https://gopkg.in/launchdarkly/go-jsonstream.v1
2426
@@ -28,7 +30,52 @@ func (u User) MarshalEasyJSON(writer *ej_jwriter.Writer) {
2830}
2931
3032func (u * User ) UnmarshalEasyJSON (lexer * jlexer.Lexer ) {
31- wrappedReader := jreader .NewReaderFromEasyJSONLexer (lexer )
32- u .ReadFromJSONReader (& wrappedReader )
33- lexer .AddError (wrappedReader .Error ())
33+ if lexer .IsNull () {
34+ lexer .Delim ('{' ) // to trigger an "expected an object, got null" error
35+ return
36+ }
37+ var fields userEquivalentStruct
38+ fields .UnmarshalEasyJSON (lexer )
39+ if lexer .Error () != nil {
40+ return
41+ }
42+ if ! fields .Key .IsDefined () {
43+ lexer .AddError (ErrMissingKey ())
44+ return
45+ }
46+ u .key = fields .Key .StringValue ()
47+ u .secondary = fields .Secondary
48+ u .ip = fields .Ip
49+ u .country = fields .Country
50+ u .email = fields .Email
51+ u .firstName = fields .FirstName
52+ u .lastName = fields .LastName
53+ u .avatar = fields .Avatar
54+ u .name = fields .Name
55+ u .anonymous = fields .Anonymous
56+ u .custom = fields .Custom
57+ if len (fields .PrivateAttributeNames ) != 0 {
58+ u .privateAttributes = make (map [UserAttribute ]struct {}, len (fields .PrivateAttributeNames ))
59+ for _ , a := range fields .PrivateAttributeNames {
60+ u .privateAttributes [UserAttribute (a )] = struct {}{}
61+ }
62+ }
63+ }
64+
65+ //go:generate easyjson -build_tags launchdarkly_easyjson -output_filename user_serialization_easyjson_generated.go user_serialization_easyjson.go
66+
67+ //easyjson:json
68+ type userEquivalentStruct struct {
69+ Key ldvalue.OptionalString `json:"key"`
70+ Secondary ldvalue.OptionalString `json:"secondary,omitempty"`
71+ Ip ldvalue.OptionalString `json:"ip,omitempty"`
72+ Country ldvalue.OptionalString `json:"country,omitempty"`
73+ Email ldvalue.OptionalString `json:"email,omitempty"`
74+ FirstName ldvalue.OptionalString `json:"firstName,omitempty"`
75+ LastName ldvalue.OptionalString `json:"lastName,omitempty"`
76+ Avatar ldvalue.OptionalString `json:"avatar,omitempty"`
77+ Name ldvalue.OptionalString `json:"name,omitempty"`
78+ Anonymous ldvalue.OptionalBool `json:"anonymous,omitempty"`
79+ Custom ldvalue.ValueMap `json:"custom,omitempty"`
80+ PrivateAttributeNames []string `json:"privateAttributeNames,omitempty"`
3481}
0 commit comments