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

refactor: Extract func coerceValue from set and remove func set #149

Merged
merged 3 commits into from
Sep 24, 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
49 changes: 27 additions & 22 deletions object.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ func (o *Object) MethodCall(methodName string, args ...Valuer) (*Value, error) {
return fn.Call(o, args...)
}

func coerceValue(iso *Isolate, val interface{}) (*Value, error) {
switch v := val.(type) {
case string, int32, uint32, int64, uint64, float64, bool, *big.Int:
// ignoring error as code cannot reach the error state as we are already
// validating the new value types in this case statement
value, _ := NewValue(iso, v)
return value, nil
case Valuer:
return v.value(), nil
default:
return nil, fmt.Errorf("v8go: unsupported object property type `%T`", v)
}
}

// Set will set a property on the Object to a given value.
// Supports all value types, eg: Object, Array, Date, Set, Map etc
// If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int)
Expand All @@ -43,35 +57,26 @@ func (o *Object) Set(key string, val interface{}) error {
if len(key) == 0 {
return errors.New("v8go: You must provide a valid property key")
}
return set(o, key, 0, val)

value, err := coerceValue(o.ctx.iso, val)
if err != nil {
return err
}

ckey := C.CString(key)
defer C.free(unsafe.Pointer(ckey))
C.ObjectSet(o.ptr, ckey, value.ptr)
return nil
}

// Set will set a given index on the Object to a given value.
// Supports all value types, eg: Object, Array, Date, Set, Map etc
// If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int)
// then a *Value will be created and set as the value property.
func (o *Object) SetIdx(idx uint32, val interface{}) error {
return set(o, "", idx, val)
}

func set(o *Object, key string, idx uint32, val interface{}) error {
var value *Value
switch v := val.(type) {
case string, int32, uint32, int64, uint64, float64, bool, *big.Int:
// ignoring error as code cannot reach the error state as we are already
// validating the new value types in this case statement
value, _ = NewValue(o.ctx.iso, v)
case Valuer:
value = v.value()
default:
return fmt.Errorf("v8go: unsupported object property type `%T`", v)
}

if len(key) > 0 {
ckey := C.CString(key)
defer C.free(unsafe.Pointer(ckey))
C.ObjectSet(o.ptr, ckey, value.ptr)
return nil
value, err := coerceValue(o.ctx.iso, val)
if err != nil {
return err
}

C.ObjectSetIdx(o.ptr, C.uint32_t(idx), value.ptr)
Expand Down
7 changes: 6 additions & 1 deletion object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ func TestObjectSet(t *testing.T) {
if err := obj.Set("a", 0); err == nil {
t.Error("expected error but got <nil>")
}
obj.SetIdx(10, "ten")
if err := obj.SetIdx(10, "ten"); err != nil {
t.Errorf("unexpected error: %v", err)
}
if err := obj.SetIdx(10, t); err == nil {
t.Error("expected error but got <nil>")
}
if ten, _ := ctx.RunScript("foo[10]", ""); ten.String() != "ten" {
t.Errorf("unexpected value: %q", ten)
}
Expand Down