diff --git a/lucirpc/options.go b/lucirpc/options.go index d98006a..bcdc99d 100644 --- a/lucirpc/options.go +++ b/lucirpc/options.go @@ -194,7 +194,8 @@ func (os *Options) UnmarshalJSON(raw []byte) error { } type optionBoolean struct { - value bool + original string + value bool } func (o *optionBoolean) AsBoolean() (bool, error) { @@ -202,7 +203,16 @@ func (o *optionBoolean) AsBoolean() (bool, error) { } func (o *optionBoolean) AsInteger() (int, error) { - return 0, NewOptionTypeMismatchError("an integer", "a boolean") + switch o.original { + case "0": + return 0, nil + + case "1": + return 1, nil + + default: + return 0, NewOptionTypeMismatchError("an integer", "a boolean") + } } func (o *optionBoolean) AsListString() ([]string, error) { @@ -210,7 +220,16 @@ func (o *optionBoolean) AsListString() ([]string, error) { } func (o *optionBoolean) AsString() (string, error) { - return "", NewOptionTypeMismatchError("a string", "a boolean") + switch o.original { + case "0", "no", "off", "false", "disabled": + return o.original, nil + + case "1", "yes", "on", "true", "enabled": + return o.original, nil + + default: + return "", NewOptionTypeMismatchError("a string", "a boolean") + } } func (o *optionBoolean) Equal(other *optionBoolean) bool { @@ -239,6 +258,7 @@ func (o *optionBoolean) UnmarshalJSON(raw []byte) error { var value bool err := json.Unmarshal(raw, &value) if err == nil { + o.original = string(raw) o.value = value return nil } @@ -253,10 +273,12 @@ func (o *optionBoolean) UnmarshalJSON(raw []byte) error { switch boolish { case "1", "yes", "on", "true", "enabled": + o.original = boolish o.value = true return nil case "0", "no", "off", "false", "disabled": + o.original = boolish o.value = false return nil @@ -289,7 +311,7 @@ func (o *optionInteger) AsListString() ([]string, error) { } func (o *optionInteger) AsString() (string, error) { - return "", NewOptionTypeMismatchError("a string", "an integer") + return strconv.Itoa(o.value), nil } func (o *optionInteger) Equal(other *optionInteger) bool { diff --git a/lucirpc/options_test.go b/lucirpc/options_test.go index 0753e28..57b3f84 100644 --- a/lucirpc/options_test.go +++ b/lucirpc/options_test.go @@ -277,4 +277,84 @@ func TestOptionsUnmarshalJSON(t *testing.T) { assert.NilError(t, err) assert.DeepEqual(t, options, want) }) + + t.Run("coerces stringy values", func(t *testing.T) { + // Given + var options lucirpc.Options + rawJSON := `{ + "option1": "1", + "option2": "yes", + "option3": "on", + "option4": "true", + "option5": "enabled", + "option6": "0", + "option7": "no", + "option8": "off", + "option9": "false", + "option10": "disabled", + "option11": "31" + }` + + // When + err := json.Unmarshal([]byte(rawJSON), &options) + + // Then + assert.NilError(t, err) + got1Integer, err := options.GetInteger("option1") + want1Integer := 1 + assert.NilError(t, err) + assert.DeepEqual(t, got1Integer, want1Integer) + got1String, err := options.GetString("option1") + want1String := "1" + assert.NilError(t, err) + assert.DeepEqual(t, got1String, want1String) + got2String, err := options.GetString("option2") + want2String := "yes" + assert.NilError(t, err) + assert.DeepEqual(t, got2String, want2String) + got3String, err := options.GetString("option3") + want3String := "on" + assert.NilError(t, err) + assert.DeepEqual(t, got3String, want3String) + got4String, err := options.GetString("option4") + want4String := "true" + assert.NilError(t, err) + assert.DeepEqual(t, got4String, want4String) + got5String, err := options.GetString("option5") + want5String := "enabled" + assert.NilError(t, err) + assert.DeepEqual(t, got5String, want5String) + got6Integer, err := options.GetInteger("option6") + want6Integer := 0 + assert.NilError(t, err) + assert.DeepEqual(t, got6Integer, want6Integer) + got6String, err := options.GetString("option6") + want6String := "0" + assert.NilError(t, err) + assert.DeepEqual(t, got6String, want6String) + got7String, err := options.GetString("option7") + want7String := "no" + assert.NilError(t, err) + assert.DeepEqual(t, got7String, want7String) + got8String, err := options.GetString("option8") + want8String := "off" + assert.NilError(t, err) + assert.DeepEqual(t, got8String, want8String) + got9String, err := options.GetString("option9") + want9String := "false" + assert.NilError(t, err) + assert.DeepEqual(t, got9String, want9String) + got10String, err := options.GetString("option10") + want10String := "disabled" + assert.NilError(t, err) + assert.DeepEqual(t, got10String, want10String) + got11Integer, err := options.GetInteger("option11") + want11Integer := 31 + assert.NilError(t, err) + assert.DeepEqual(t, got11Integer, want11Integer) + got11String, err := options.GetString("option11") + want11String := "31" + assert.NilError(t, err) + assert.DeepEqual(t, got11String, want11String) + }) }