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

prepare 2.1.0 release #13

Merged
merged 147 commits into from
Dec 14, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
147 commits
Select commit Hold shift + click to select a range
75f29a1
implement Value type for arbitrary JSON values
eli-darkly Dec 12, 2019
14cea8b
force CI rebuild
eli-darkly Dec 12, 2019
529f2a1
add go get
eli-darkly Dec 12, 2019
25fdf9e
fix go get
eli-darkly Dec 13, 2019
7478aa3
fix lint in CI
eli-darkly Dec 13, 2019
845020e
add Equal()
eli-darkly Dec 13, 2019
30fcb62
add EvaluationDetail and EvaluationReason
eli-darkly Dec 13, 2019
82923f6
fix import path
eli-darkly Dec 13, 2019
141acc1
readme fixes
eli-darkly Dec 13, 2019
0f673b0
update for v2
eli-darkly Dec 13, 2019
0342b4b
Merge branch 'v2' into eb/ch49035/detail-reason
eli-darkly Dec 13, 2019
d327ff8
fix doc comments
eli-darkly Dec 13, 2019
681a43d
add OptionalString
eli-darkly Dec 17, 2019
3220b69
misc cleanup, method renaming, better test coverage
eli-darkly Jan 23, 2020
44328ab
package comments
eli-darkly Jan 23, 2020
4cfc041
changed repo name
eli-darkly Jan 23, 2020
62437a9
numbers can't have leading decimal point
eli-darkly Jan 23, 2020
4dd29c8
Merge pull request #1 from launchdarkly/eb/ch49035/value-type
eli-darkly Jan 24, 2020
fd5ee91
actually we decided on go-sdk-common, not go-sdk-core
eli-darkly Jan 24, 2020
4a686f5
add license file
eli-darkly Jan 24, 2020
293c8b2
Merge branch 'public-v1' into v1
eli-darkly Jan 24, 2020
16fc315
OptionalString improvements + misc fixes
eli-darkly Jan 24, 2020
412e802
add OrElse
eli-darkly Jan 24, 2020
5e07050
add tests
eli-darkly Jan 24, 2020
7f9a2eb
comment
eli-darkly Jan 24, 2020
871db18
Merge branch 'v2' of github.com:launchdarkly/go-sdk-common-private in…
eli-darkly Jan 24, 2020
ec60b93
remove unsafe interface{} usage
eli-darkly Jan 24, 2020
bfb9c44
copy User and related types from go-server-sdk
eli-darkly Jan 24, 2020
7a88acd
OptionalString improvements + misc fixes (#2)
eli-darkly Jan 24, 2020
a626c5e
(common v2/SDK v5) don't use pointers or interface{}s in User
eli-darkly Jan 28, 2020
b57319b
lint
eli-darkly Jan 28, 2020
e5a23b3
lint
eli-darkly Jan 28, 2020
16c7079
Merge branch 'eb/ch58941/copy-user' into eb/ch58941/common-v2-user
eli-darkly Jan 28, 2020
312476d
rm references to obsolete function
eli-darkly Jan 28, 2020
87d4910
Merge branch 'eb/ch58941/copy-user' into eb/ch58941/common-v2-user
eli-darkly Jan 28, 2020
576fd88
(v2 - #1) copy User and related types from go-server-sdk (#3)
eli-darkly Jan 28, 2020
558a682
Merge branch 'v2' into eb/ch58941/common-v2-user
eli-darkly Jan 28, 2020
e63561b
Merge pull request #4 from launchdarkly/eb/ch58941/common-v2-user
eli-darkly Jan 28, 2020
88414be
hide all User fields, improve internal structure, add getters
eli-darkly Jan 28, 2020
b0924fd
lint
eli-darkly Jan 28, 2020
67e75cc
Merge pull request #5 from launchdarkly/eb/ch58941/hide-user-fields
eli-darkly Jan 28, 2020
a9f1f8a
Merge branch 'v1' into v2
eli-darkly Jan 29, 2020
7ccd883
Merge branch 'eb/ch63370/remove-unsafe' into eb/ch58941/user-accessors
eli-darkly Jan 29, 2020
7a480b8
add convenience methods for enumerable types
eli-darkly Jan 29, 2020
4058727
User model improvements related to custom/private attributes
eli-darkly Jan 29, 2020
6ad0ad0
lint
eli-darkly Jan 29, 2020
5db5e14
Merge branch 'v2' into eb/ch63370/remove-unsafe
eli-darkly Jan 29, 2020
8459cbe
Merge branch 'eb/ch63370/remove-unsafe' into eb/ch58941/value-enumera…
eli-darkly Jan 29, 2020
4df7f25
Merge branch 'eb/ch58941/value-enumeration' into eb/ch58941/user-acce…
eli-darkly Jan 29, 2020
2284162
Merge pull request #6 from launchdarkly/eb/ch63370/remove-unsafe
eli-darkly Jan 30, 2020
ec4cad1
Merge pull request #7 from launchdarkly/eb/ch58941/value-enumeration
eli-darkly Jan 30, 2020
3e63beb
Merge pull request #8 from launchdarkly/eb/ch58941/user-accessors
eli-darkly Jan 30, 2020
e588112
Merge branch 'public-v1' into v1
eli-darkly Feb 1, 2020
b1956fd
update release config
eli-darkly Feb 1, 2020
3f638e7
Merge branch 'public-v1' into v1
eli-darkly Feb 1, 2020
50130e8
Merge branch 'v1' into v2
eli-darkly Feb 1, 2020
7688db6
update release config
eli-darkly Feb 1, 2020
aece760
Merge branch 'public-v1' into v1
eli-darkly Feb 1, 2020
4ef5401
Merge branch 'v2' into eb/ch63866/detail-reason
eli-darkly Feb 1, 2020
256b653
fix package references
eli-darkly Feb 1, 2020
0b761e2
Merge pull request #9 from launchdarkly/eb/ch63866/detail-reason
eli-darkly Feb 3, 2020
547cd23
Merge branch 'v1' of github.com:launchdarkly/go-sdk-common into v1
eli-darkly Feb 4, 2020
065bb63
Merge branch 'v1' into v2
eli-darkly Feb 4, 2020
357513b
add ldlog package to go-sdk-common
eli-darkly Feb 4, 2020
1f08c69
lint
eli-darkly Feb 4, 2020
f7d094e
drop Go 1.8-1.11 and update linter
eli-darkly Feb 4, 2020
fb76722
gitignore
eli-darkly Feb 4, 2020
085fb8b
Merge pull request #11 from launchdarkly/eb/ch62105/drop-old-go
eli-darkly Feb 4, 2020
ebb06d6
Merge branch 'v2' into eb/ch64207/ldlog-common
eli-darkly Feb 4, 2020
0490d52
lint
eli-darkly Feb 4, 2020
08c2cf5
Merge pull request #10 from launchdarkly/eb/ch64207/ldlog-common
eli-darkly Feb 4, 2020
0e5056e
add ldtime package for time helpers
eli-darkly Feb 23, 2020
9ce753b
Merge pull request #12 from launchdarkly/eb/ch64206/time-type
eli-darkly Feb 24, 2020
ecc98c6
add Go 1.14 in CI
eli-darkly Mar 2, 2020
d551adb
Merge pull request #13 from launchdarkly/eb/ch67936/go-1.14
eli-darkly Mar 2, 2020
e9701ec
Merge branch 'v1' into v2
eli-darkly Mar 2, 2020
24c7e66
desupport Go 1.12
eli-darkly Mar 2, 2020
bdf9ef7
makefile improvement
eli-darkly Mar 2, 2020
82ce336
Merge pull request #14 from launchdarkly/eb/ch67936/no-go-1.12
eli-darkly Mar 2, 2020
e085a3a
Merge branch 'public-v2' into v2
eli-darkly Apr 1, 2020
7b18d72
make repo a module
eli-darkly Jun 4, 2020
343917d
don't install dep
eli-darkly Jun 4, 2020
6798fbe
yaml fix
eli-darkly Jun 4, 2020
0e0d49f
update golangci-lint + misc code cleanup
eli-darkly Jun 4, 2020
a9985bd
Merge branch 'eb/ch78747/linter-update' into eb/ch78731/modules
eli-darkly Jun 4, 2020
79fddc6
add methods for detecting current log level
eli-darkly Jun 4, 2020
a4bcae8
enforce consistent import groups
eli-darkly Jun 4, 2020
37676bf
enable stylecheck, fix comment
eli-darkly Jun 4, 2020
c1a52d2
add prerelease readme note
eli-darkly Jun 4, 2020
8e0ba06
Merge pull request #17 from launchdarkly/eb/ch77304/detect-debug-level
eli-darkly Jun 4, 2020
9bca369
Merge pull request #15 from launchdarkly/eb/ch78747/linter-update
eli-darkly Jun 4, 2020
09af655
Merge pull request #16 from launchdarkly/eb/ch78731/modules
eli-darkly Jun 4, 2020
3252370
Merge branch 'v2' of github.com:launchdarkly/go-sdk-common into v2
eli-darkly Jun 4, 2020
4547f29
improve test coverage and enforce coverage goals (#18)
eli-darkly Jun 11, 2020
306b165
update readme note about import path, add godoc badge
eli-darkly Jun 12, 2020
78993dd
better badge
eli-darkly Jun 12, 2020
d882b28
omit unset properties in user JSON instead of serializing null value
eli-darkly Jun 16, 2020
4c03ea3
don't allocate extra objects when setting user builder properties
eli-darkly Jun 16, 2020
5dbe2b1
Merge pull request #19 from launchdarkly/eb/ch79884/compact-user-json
eli-darkly Jun 16, 2020
c3da53a
Merge pull request #20 from launchdarkly/eb/ch77304/single-user-build…
eli-darkly Jun 16, 2020
2608fda
add generic user attr setter and more Value helper methods
eli-darkly Jun 16, 2020
d61956f
add benchmarks and enforce zero-allocation goals
eli-darkly Jun 16, 2020
5065348
Merge pull request #21 from launchdarkly/eb/ch79888/set-any-user-attr
eli-darkly Jun 16, 2020
fbe1e72
Merge pull request #22 from launchdarkly/eb/ch77270/benchmarks
eli-darkly Jun 16, 2020
467c837
implement streaming JSON serialization (#23)
eli-darkly Jun 17, 2020
ea7567b
fix bug in JSONBuffer state when writing zeroes
eli-darkly Jun 17, 2020
201d583
Merge pull request #24 from launchdarkly/eb/ch79944/jsonstream-zero-bug
eli-darkly Jun 17, 2020
503da9b
fix note about import path
eli-darkly Jun 18, 2020
2422e4e
go mod tidy
eli-darkly Jun 18, 2020
50ddf12
fix JSONBuffer string escaping, + slight refactor
eli-darkly Jun 18, 2020
0e2db4d
remove accidental inclusions from another branch
eli-darkly Jun 18, 2020
b33a319
lint
eli-darkly Jun 18, 2020
cc049b5
remove inapplicable comments
eli-darkly Jun 18, 2020
454b10c
add ability to send buffered JSON output to another writer
eli-darkly Jun 18, 2020
7aec220
Merge pull request #25 from launchdarkly/eb/ch79944/json-string-escaping
eli-darkly Jun 19, 2020
660a5ba
Merge pull request #26 from launchdarkly/eb/ch79944/stream-to-writer
eli-darkly Jun 19, 2020
2d6f974
Merge branch 'v2' of github.com:launchdarkly/go-sdk-common into v2
eli-darkly Jun 24, 2020
1bfadb3
Merge branch 'v2' of github.com:launchdarkly/go-sdk-common into v2
eli-darkly Jun 24, 2020
cc24b10
add log test helper package
eli-darkly Jun 25, 2020
2360388
Merge branch 'v2' of github.com:launchdarkly/go-sdk-common into v2
eli-darkly Jul 1, 2020
d755157
Merge pull request #27 from launchdarkly/eb/ch80986/mock-log
eli-darkly Jul 6, 2020
68c56ca
add UnmarshalText and other helper methods to OptionalString
eli-darkly Jul 6, 2020
e4e7b0f
Merge pull request #29 from launchdarkly/eb/ch81912/opt-string-parsing
eli-darkly Jul 6, 2020
290b7ab
use go-test-helpers v2 (removes unwanted eventsource dependency) (#28)
eli-darkly Jul 6, 2020
70fdf76
Merge branch 'v2' of github.com:launchdarkly/go-sdk-common into v2
eli-darkly Jul 6, 2020
cb3c12e
user unmarshaling should fail if key is missing (#30)
eli-darkly Aug 6, 2020
5191ba8
Merge branch 'v2' of github.com:launchdarkly/go-sdk-common into v2
eli-darkly Aug 6, 2020
ac7a4c2
add OptionalInt type
eli-darkly Sep 3, 2020
a383e5c
test coverage
eli-darkly Sep 3, 2020
6ff09df
keep method signature of NewEvaluationDetail the same as it used to be
eli-darkly Sep 3, 2020
bd5f1bf
comment
eli-darkly Sep 3, 2020
3dca288
Merge pull request #31 from launchdarkly/eb/ch88692/optional-int
eli-darkly Sep 3, 2020
7a1f7e4
add OptionalBool type and use it for User.Anonymous (#32)
eli-darkly Sep 3, 2020
82e9f20
add ldlogtest helper for dumping captured log output
eli-darkly Sep 3, 2020
cfcb090
Merge pull request #33 from launchdarkly/eb/ch88720/dump-log
eli-darkly Sep 8, 2020
434739c
Merge branch 'v2' of github.com:launchdarkly/go-sdk-common into v2
eli-darkly Sep 8, 2020
53178e7
add Go 1.15 build and remove beta changelog
eli-darkly Sep 18, 2020
6302689
update Go version in readme
eli-darkly Sep 18, 2020
be72603
Merge pull request #34 from launchdarkly/eb/ch89155/go-1.15
eli-darkly Sep 18, 2020
d9215ea
rm prerelease note
eli-darkly Sep 18, 2020
7556128
Merge branch 'v2' of github.com:launchdarkly/go-sdk-common into v2
eli-darkly Sep 18, 2020
21ad18b
better error reporting when unmarshaling User, OptionalString, etc. (…
eli-darkly Oct 8, 2020
50ef603
merge from public after release
LaunchDarklyCI Oct 8, 2020
7844258
add IsDefined() methods to optional-like types
eli-darkly Oct 2, 2020
f3db75e
Merge pull request #36 from launchdarkly/eb/ch91412/is-defined
eli-darkly Oct 9, 2020
b545324
better copy-on-write behavior for maps/slices; expose map & array types
eli-darkly Oct 10, 2020
1e30957
Merge pull request #37 from launchdarkly/eb/ch92116/copy-on-write
eli-darkly Oct 16, 2020
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
Prev Previous commit
Next Next commit
add OptionalBool type and use it for User.Anonymous (#32)
* add OptionalBool type and use it for User.Anonymous

* comment
  • Loading branch information
eli-darkly authored Sep 3, 2020
commit 7a1f7e499f3207964afb5330d2f03bbbe3f09449
8 changes: 4 additions & 4 deletions lduser/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ type User struct {
lastName ldvalue.OptionalString
avatar ldvalue.OptionalString
name ldvalue.OptionalString
anonymous ldvalue.Value
anonymous ldvalue.OptionalBool
custom ldvalue.Value
privateAttributes map[UserAttribute]struct{}
}
Expand Down Expand Up @@ -90,7 +90,7 @@ func (u User) GetAttribute(attribute UserAttribute) ldvalue.Value {
case NameAttribute:
return u.name.AsValue()
case AnonymousAttribute:
return u.anonymous
return u.anonymous.AsValue()
default:
value, _ := u.GetCustom(string(attribute))
return value
Expand Down Expand Up @@ -157,7 +157,7 @@ func (u User) GetAnonymous() bool {
// GetAnonymousOptional returns the anonymous attribute of the user, with a second value indicating
// whether that attribute was defined for the user or not.
func (u User) GetAnonymousOptional() (bool, bool) {
return u.anonymous.BoolValue(), !u.anonymous.IsNull()
return u.anonymous.Get()
}

// GetCustom returns a custom attribute of the user by name. The boolean second return value indicates
Expand Down Expand Up @@ -207,7 +207,7 @@ func (u User) Equal(other User) bool {
u.lastName != other.lastName ||
u.avatar != other.avatar ||
u.name != other.name ||
!u.anonymous.Equal(other.anonymous) {
u.anonymous != other.anonymous {
return false
}
if !u.custom.Equal(other.custom) {
Expand Down
13 changes: 8 additions & 5 deletions lduser/user_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ func NewUser(key string) User {

// NewAnonymousUser creates a new anonymous user identified by the given key.
func NewAnonymousUser(key string) User {
return User{key: key, anonymous: ldvalue.Bool(true)}
return User{key: key, anonymous: ldvalue.NewOptionalBool(true)}
}

// UserBuilder is a mutable object that uses the Builder pattern to specify properties for a User.
Expand Down Expand Up @@ -150,7 +150,7 @@ type userBuilderImpl struct {
lastName ldvalue.OptionalString
avatar ldvalue.OptionalString
name ldvalue.OptionalString
anonymous ldvalue.Value
anonymous ldvalue.OptionalBool
custom ldvalue.ObjectBuilder
privateAttrs map[UserAttribute]struct{}
lastAttributeCanMakePrivate UserAttribute
Expand Down Expand Up @@ -246,7 +246,7 @@ func (b *userBuilderImpl) Name(value string) UserBuilderCanMakeAttributePrivate
}

func (b *userBuilderImpl) Anonymous(value bool) UserBuilder {
b.anonymous = ldvalue.Bool(value)
b.anonymous = ldvalue.NewOptionalBool(value)
return b
}

Expand Down Expand Up @@ -293,8 +293,11 @@ func (b *userBuilderImpl) SetAttribute(
case NameAttribute:
setOptString(&b.name)
case AnonymousAttribute:
if value.IsBool() || value.IsNull() {
b.anonymous = value
switch {
case value.IsNull():
b.anonymous = ldvalue.OptionalBool{}
case value.IsBool():
b.anonymous = ldvalue.NewOptionalBool(value.BoolValue())
}
okPrivate = false
default:
Expand Down
4 changes: 2 additions & 2 deletions lduser/user_serialization.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type userForDeserialization struct {
LastName ldvalue.OptionalString `json:"lastName"`
Avatar ldvalue.OptionalString `json:"avatar"`
Name ldvalue.OptionalString `json:"name"`
Anonymous ldvalue.Value `json:"anonymous"`
Anonymous ldvalue.OptionalBool `json:"anonymous"`
Custom ldvalue.Value `json:"custom"`
PrivateAttributeNames []UserAttribute `json:"privateAttributeNames"`
}
Expand Down Expand Up @@ -122,7 +122,7 @@ func (u User) WriteToJSONBuffer(j *jsonstream.JSONBuffer) {
maybeWriteStringProperty(j, "lastName", u.lastName)
maybeWriteStringProperty(j, "avatar", u.avatar)
maybeWriteStringProperty(j, "name", u.name)
if !u.anonymous.IsNull() {
if u.anonymous.IsDefined() {
j.WriteName("anonymous")
j.WriteBool(u.anonymous.BoolValue())
}
Expand Down
4 changes: 4 additions & 0 deletions ldvalue/benchmark_data_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package ldvalue

var (
benchmarkBoolValue = true
benchmarkBoolPointer = &benchmarkBoolValue
benchmarkOptBoolWithValue = NewOptionalBool(benchmarkBoolValue)
benchmarkIntValue = 3333
benchmarkIntPointer = &benchmarkIntValue
benchmarkOptIntWithValue = NewOptionalInt(benchmarkIntValue)
Expand All @@ -16,6 +19,7 @@ var (
benchmarkSerializeArrayValue = ArrayOf(String("a"), String("b"), String("c"))
benchmarkSerializeObjectValue = ObjectBuild().Set("a", Int(1)).Set("b", Int(2)).Set("c", Int(3)).Build()

benchmarkOptBoolResult OptionalBool
benchmarkOptIntResult OptionalInt
benchmarkOptStringResult OptionalString
benchmarkStringResult string
Expand Down
7 changes: 6 additions & 1 deletion ldvalue/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ package ldvalue

// string literals should be defined here if they are referenced in multiple files

const nullAsJSON = "null"
const (
trueString = "true"
falseString = "false"
nullAsJSON = "null"
noneDescription = "[none]"
)

// ValueType is defined in value_base.go

Expand Down
163 changes: 163 additions & 0 deletions ldvalue/optional_bool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package ldvalue

import (
"errors"

"gopkg.in/launchdarkly/go-sdk-common.v2/jsonstream"
)

// OptionalBool represents a bool that may or may not have a value. This is similar to using a
// bool pointer to distinguish between a false value and nil, but it is safer because it does not
// expose a pointer to any mutable value.
//
// To create an instance with a bool value, use NewOptionalBool. There is no corresponding method
// for creating an instance with no value; simply use the empty literal OptionalBool{}.
//
// ob1 := NewOptionalBool(1)
// ob2 := NewOptionalBool(false) // this has a value which is false
// ob3 := OptionalBool{} // this does not have a value
//
// This can also be used as a convenient way to construct a bool pointer within an expression.
// For instance, this example causes myIntPointer to point to the bool value true:
//
// var myBoolPointer *int = NewOptionalBool(true).AsPointer()
//
// This type is used in the Anonymous property of lduser.User, and for other similar fields in
// the LaunchDarkly Go SDK where a bool value may or may not be defined.
type OptionalBool struct {
value bool
hasValue bool
}

// NewOptionalBool constructs an OptionalBool that has a bool value.
//
// There is no corresponding method for creating an OptionalBool with no value; simply use the
// empty literal OptionalBool{}.
func NewOptionalBool(value bool) OptionalBool {
return OptionalBool{value: value, hasValue: true}
}

// NewOptionalBoolFromPointer constructs an OptionalBool from a bool pointer. If the pointer is
// non-nil, then the OptionalBool copies its value; otherwise the OptionalBool has no value.
func NewOptionalBoolFromPointer(valuePointer *bool) OptionalBool {
if valuePointer == nil {
return OptionalBool{hasValue: false}
}
return OptionalBool{value: *valuePointer, hasValue: true}
}

// IsDefined returns true if the OptionalBool contains a bool value, or false if it has no value.
func (o OptionalBool) IsDefined() bool {
return o.hasValue
}

// BoolValue returns the OptionalBool's value, or false if it has no value.
func (o OptionalBool) BoolValue() bool {
return o.value
}

// Get is a combination of BoolValue and IsDefined. If the OptionalBool contains a bool value, it
// returns that value and true; otherwise it returns false and false.
func (o OptionalBool) Get() (bool, bool) {
return o.value, o.hasValue
}

// OrElse returns the OptionalBool's value if it has one, or else the specified fallback value.
func (o OptionalBool) OrElse(valueIfEmpty bool) bool {
if o.hasValue {
return o.value
}
return valueIfEmpty
}

// AsPointer returns the OptionalBool's value as a bool pointer if it has a value, or nil
// otherwise.
//
// The bool value, if any, is copied rather than returning to a pointer to the internal field.
func (o OptionalBool) AsPointer() *bool {
if o.hasValue {
v := o.value
return &v
}
return nil
}

// AsValue converts the OptionalBool to a Value, which is either Null() or a boolean value.
func (o OptionalBool) AsValue() Value {
if o.hasValue {
return Bool(o.value)
}
return Null()
}

// String is a debugging convenience method that returns a description of the OptionalBool. This
// is either "true", "false, or "[none]" if it has no value.
func (o OptionalBool) String() string {
if o.hasValue {
if o.value {
return trueString
}
return falseString
}
return noneDescription
}

// MarshalJSON converts the OptionalBool to its JSON representation.
//
// The output will be either a JSON boolean or null. Note that the "omitempty" tag for a struct
// field will not cause an empty OptionalBool field to be omitted; it will be output as null.
// If you want to completely omit a JSON property when there is no value, it must be a bool
// pointer instead of an OptionalBool; use the AsPointer() method to get a pointer.
func (o OptionalBool) MarshalJSON() ([]byte, error) {
return o.AsValue().MarshalJSON()
}

// UnmarshalJSON parses an OptionalBool from JSON.
//
// The input must be either a JSON number that is a boolean or null.
func (o *OptionalBool) UnmarshalJSON(data []byte) error {
var v Value
if err := v.UnmarshalJSON(data); err != nil {
return err // COVERAGE: should not be possible, parser normally doesn't pass malformed content to UnmarshalJSON
}
switch {
case v.IsNull():
*o = OptionalBool{}
case v.IsBool():
*o = NewOptionalBool(v.BoolValue())
default:
*o = OptionalBool{}
return errors.New("expected boolean or null")
}
return nil
}

// WriteToJSONBuffer provides JSON serialization for OptionalBool with the jsonstream API.
//
// The JSON output format is identical to what is produced by json.Marshal, but this implementation is
// more efficient when building output with JSONBuffer. See the jsonstream package for more details.
func (o OptionalBool) WriteToJSONBuffer(j *jsonstream.JSONBuffer) {
o.AsValue().WriteToJSONBuffer(j)
}

// MarshalText implements the encoding.TextMarshaler interface.
func (o OptionalBool) MarshalText() ([]byte, error) {
if o.hasValue {
if o.value {
return []byte(trueString), nil
}
return []byte(falseString), nil
}
return []byte(""), nil
}

// UnmarshalText implements the encoding.TextUnmarshaler interface.
//
// This allows OptionalBool to be used with packages that can parse text content, such as gcfg.
func (o *OptionalBool) UnmarshalText(text []byte) error {
if len(text) == 0 {
*o = OptionalBool{}
return nil
}
return o.UnmarshalJSON(text)
}
33 changes: 33 additions & 0 deletions ldvalue/optional_bool_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ldvalue

import "testing"

func BenchmarkNewOptionalBoolNoAlloc(b *testing.B) {
for i := 0; i < b.N; i++ {
benchmarkOptBoolResult = NewOptionalBool(benchmarkBoolValue)
}
}

func BenchmarkNewOptionalBoolFromPointerNoAlloc(b *testing.B) {
for i := 0; i < b.N; i++ {
benchmarkOptBoolResult = NewOptionalBoolFromPointer(benchmarkBoolPointer)
}
}

func BenchmarkOptionalBoolValueNoAlloc(b *testing.B) {
for i := 0; i < b.N; i++ {
benchmarkBoolResult = benchmarkOptBoolWithValue.BoolValue()
}
}

func BenchmarkOptionalBoolGetNoAlloc(b *testing.B) {
for i := 0; i < b.N; i++ {
benchmarkBoolResult, _ = benchmarkOptBoolWithValue.Get()
}
}

func BenchmarkOptionalBoolAsValueNoAlloc(b *testing.B) {
for i := 0; i < b.N; i++ {
benchmarkValueResult = benchmarkOptBoolWithValue.AsValue()
}
}
Loading