Skip to content
This repository has been archived by the owner on Mar 9, 2022. It is now read-only.

feat: OptionalString and UnixFSShardingSizeThreshold #149

Merged
merged 5 commits into from
Oct 28, 2021
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
3 changes: 2 additions & 1 deletion internal.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package config

type Internal struct {
Bitswap *InternalBitswap `json:",omitempty"` // This is omitempty since we are expecting to make changes to all subcomponents of Internal
Bitswap *InternalBitswap `json:",omitempty"` // This is omitempty since we are expecting to make changes to all subcomponents of Internal
UnixFSShardingSizeThreshold *OptionalString `json:",omitempty"`
}

type InternalBitswap struct {
Expand Down
52 changes: 52 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,55 @@ func (p OptionalInteger) String() string {

var _ json.Unmarshaler = (*OptionalInteger)(nil)
var _ json.Marshaler = (*OptionalInteger)(nil)

// OptionalString represents a string that has a default value
//
// When encoded in json, Default is encoded as "null"
type OptionalString struct {
value *string
}

// WithDefault resolves the integer with the given default.
func (p *OptionalString) WithDefault(defaultValue string) (value string) {
if p == nil || p.value == nil {
return defaultValue
}
return *p.value
}

// IsDefault returns if this is a default optional integer
func (p *OptionalString) IsDefault() bool {
return p == nil || p.value == nil
}

func (p OptionalString) MarshalJSON() ([]byte, error) {
if p.value != nil {
return json.Marshal(p.value)
}
return json.Marshal(nil)
}

func (p *OptionalString) UnmarshalJSON(input []byte) error {
switch string(input) {
case "null", "undefined":
*p = OptionalString{}
default:
var value string
err := json.Unmarshal(input, &value)
if err != nil {
return err
}
*p = OptionalString{value: &value}
}
return nil
}

func (p OptionalString) String() string {
if p.value == nil {
return "default"
}
return fmt.Sprintf("%d", p.value)
}

var _ json.Unmarshaler = (*OptionalInteger)(nil)
var _ json.Marshaler = (*OptionalInteger)(nil)
98 changes: 97 additions & 1 deletion types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,106 @@ func TestOptionalInteger(t *testing.T) {
for _, invalid := range []string{
"foo", "-1.1", "1.1", "0.0", "[]",
} {
var p Priority
var p OptionalInteger
err := json.Unmarshal([]byte(invalid), &p)
if err == nil {
t.Errorf("expected to fail to decode %s as a priority", invalid)
}
}
}

func TestOptionalString(t *testing.T) {
makeStringPointer := func(v string) *string {
return &v
}

var defaultOptionalString OptionalString
if !defaultOptionalString.IsDefault() {
t.Fatal("should be the default")
}
if val := defaultOptionalString.WithDefault(""); val != "" {
t.Errorf("optional integer should have been empty, got %s", val)
}

if val := defaultOptionalString.WithDefault("foo"); val != "foo" {
t.Errorf("optional integer should have been foo, got %s", val)
}

var filledStr OptionalString
filledStr = OptionalString{value: makeStringPointer("foo")}
if filledStr.IsDefault() {
t.Fatal("should not be the default")
}
if val := filledStr.WithDefault("bar"); val != "foo" {
t.Errorf("optional integer should have been foo, got %s", val)
}

filledStr = OptionalString{value: makeStringPointer("")}
if val := filledStr.WithDefault("foo"); val != "" {
t.Errorf("optional integer should have been 0, got %s", val)
}

for jsonStr, goValue := range map[string]OptionalString{
"null": {},
"\"0\"": {value: makeStringPointer("0")},
`"1"`: {value: makeStringPointer("1")},
`"-1"`: {value: makeStringPointer("-1")},
`"qwerty"`: {value: makeStringPointer("qwerty")},
} {
var d OptionalString
err := json.Unmarshal([]byte(jsonStr), &d)
if err != nil {
t.Fatal(err)
}

if goValue.value == nil && d.value == nil {
} else if goValue.value == nil && d.value != nil {
t.Errorf("expected default, got %s", d)
} else if *d.value != *goValue.value {
t.Fatalf("expected %s, got %s", goValue, d)
}

// Reverse
out, err := json.Marshal(goValue)
if err != nil {
t.Fatal(err)
}
if string(out) != jsonStr {
t.Fatalf("expected %s, got %s", jsonStr, string(out))
}
}

// marshal with omitempty
type Foo struct {
S *OptionalString `json:",omitempty"`
}
out, err := json.Marshal(new(Foo))
if err != nil {
t.Fatal(err)
}
expected := "{}"
if string(out) != expected {
t.Fatal("expected omitempty to omit the optional integer")
}
// unmarshal from omitempty output and get default value
var foo2 Foo
if err := json.Unmarshal(out, &foo2); err != nil {
t.Fatalf("%s failed to unmarshall with %s", string(out), err)
}
if s := foo2.S.WithDefault("foo"); s != "foo" {
t.Fatalf("expected default value to be used, got %s", s)
}
if !foo2.S.IsDefault() {
t.Fatal("expected value to be the default")
}

for _, invalid := range []string{
"[]", "{}", "0", "a", "'b'",
} {
var p OptionalString
err := json.Unmarshal([]byte(invalid), &p)
if err == nil {
t.Errorf("expected to fail to decode %s as an optional string", invalid)
}
}
}