Skip to content

Commit

Permalink
add AfterSet
Browse files Browse the repository at this point in the history
  • Loading branch information
linkdata committed Dec 3, 2024
1 parent 01a2438 commit d71ad2d
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 1 deletion.
44 changes: 44 additions & 0 deletions afterset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package jaws

import "time"

type AfterSetter[T comparable] struct {
Binding[T]
Func func()
}

func (as *AfterSetter[T]) Set(value T) (err error) {
if err = as.Binding.Set(value); err == nil {
as.Func()
}
return
}

func (as *AfterSetter[T]) JawsSet(elem *Element, value T) (err error) {
return as.Set(value)
}

func (as *AfterSetter[T]) JawsSetString(e *Element, val string) (err error) {
return as.JawsSet(e, any(val).(T))
}

func (as *AfterSetter[T]) JawsSetFloat(e *Element, val float64) (err error) {
return as.JawsSet(e, any(val).(T))
}

func (as *AfterSetter[T]) JawsSetBool(e *Element, val bool) (err error) {
return as.JawsSet(e, any(val).(T))
}

func (as *AfterSetter[T]) JawsSetTime(elem *Element, value time.Time) error {
return as.JawsSet(elem, any(value).(T))
}

// AfterSet returns a wrapped Binding with a function to call after a
// successful Set.
func AfterSet[T comparable](bind Binding[T], fn func()) *AfterSetter[T] {
return &AfterSetter[T]{
Binding: bind,
Func: fn,
}
}
88 changes: 88 additions & 0 deletions afterset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package jaws

import (
"sync"
"testing"
"time"
)

func TestAfterSet_String(t *testing.T) {
var mu sync.Mutex
var value string
var called int

fn := func() {
called++
}

as := AfterSet(Bind(&mu, &value), fn)
if err := as.JawsSetString(nil, "foo"); err != nil {
t.Error(err)
}
if called != 1 {
t.Error(called)
}
if tag := as.JawsGetTag(nil); tag != &value {
t.Error(tag)
}
if err := as.JawsSetString(nil, "foo"); err != ErrValueUnchanged {
t.Error(err)
}
if called != 1 {
t.Error(called)
}
}

func TestAfterSet_Float(t *testing.T) {
var mu sync.Mutex
var value float64
var called bool

fn := func() {
called = true
}

as := AfterSet(Bind(&mu, &value), fn)
if err := as.JawsSetFloat(nil, 1); err != nil {
t.Error(err)
}
if !called {
t.Error(called)
}
}

func TestAfterSet_Bool(t *testing.T) {
var mu sync.Mutex
var value bool
var called bool

fn := func() {
called = true
}

as := AfterSet(Bind(&mu, &value), fn)
if err := as.JawsSetBool(nil, !value); err != nil {
t.Error(err)
}
if !called {
t.Error(called)
}
}

func TestAfterSet_Time(t *testing.T) {
var mu sync.Mutex
var value time.Time
var called bool

fn := func() {
called = true
}

as := AfterSet(Bind(&mu, &value), fn)
if err := as.JawsSetTime(nil, time.Now()); err != nil {
t.Error(err)
}
if !called {
t.Error(called)
}
}
2 changes: 1 addition & 1 deletion bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (bind Binding[T]) JawsGetTime(elem *Element) time.Time {
}

func (bind Binding[T]) JawsSetTime(elem *Element, value time.Time) error {
return bind.Set(any(value).(T))
return bind.JawsSet(elem, any(value).(T))
}

// Bind returns a Binding[T] with the given sync.Locker (or RWLocker) and a pointer to the underlying value of type T.
Expand Down

0 comments on commit d71ad2d

Please sign in to comment.