github.com/0chain/gosdk@v1.17.11/wasmsdk/jsbridge/sync.go (about)

     1  //go:build js && wasm
     2  // +build js,wasm
     3  
     4  package jsbridge
     5  
     6  import (
     7  	"reflect"
     8  	"syscall/js"
     9  )
    10  
    11  type SyncInvoker func(fn reflect.Value, in []reflect.Value) js.Value
    12  
    13  func Sync(funcType reflect.Type) (SyncInvoker, error) {
    14  	outputBinder, err := NewOutputBuilder(funcType).Build()
    15  	if err != nil {
    16  		return nil, err
    17  	}
    18  
    19  	switch funcType.NumOut() {
    20  	case 0:
    21  		return func(fn reflect.Value, in []reflect.Value) (result js.Value) {
    22  
    23  			defer func() {
    24  				if r := recover(); r != nil {
    25  					result = NewJsError(r)
    26  				}
    27  			}()
    28  
    29  			fn.Call(in)
    30  
    31  			return
    32  
    33  		}, nil
    34  	case 1:
    35  		outputType := funcType.Out(0)
    36  		//func(...)error
    37  		if outputType.String() == TypeError {
    38  			return func(fn reflect.Value, in []reflect.Value) (result js.Value) {
    39  
    40  				defer func() {
    41  					if r := recover(); r != nil {
    42  						result = NewJsError(r)
    43  					}
    44  				}()
    45  
    46  				err := fn.Call(in)[0]
    47  
    48  				// err != nil
    49  				if !err.IsNil() {
    50  					result = NewJsError(err.Interface())
    51  				}
    52  
    53  				return
    54  			}, nil
    55  		} else { //func(...) T
    56  			return func(fn reflect.Value, in []reflect.Value) (result js.Value) {
    57  
    58  				defer func() {
    59  					if r := recover(); r != nil {
    60  						result = NewJsError(r)
    61  					}
    62  				}()
    63  
    64  				output := fn.Call(in)
    65  
    66  				result = outputBinder(output)[0]
    67  
    68  				return
    69  
    70  			}, nil
    71  		}
    72  	case 2:
    73  
    74  		errOutputType := funcType.Out(1)
    75  
    76  		if errOutputType.String() != TypeError {
    77  			return nil, ErrFuncNotSupported
    78  		}
    79  		//func(...) (T,error)
    80  		return func(fn reflect.Value, in []reflect.Value) (result js.Value) {
    81  			defer func() {
    82  				if r := recover(); r != nil {
    83  					result = NewJsError(r)
    84  				}
    85  			}()
    86  			output := fn.Call(in)
    87  
    88  			err := output[1]
    89  
    90  			// err == nil
    91  			if err.IsNil() {
    92  				result = outputBinder(output)[0]
    93  			} else {
    94  				result = NewJsError(err.Interface())
    95  			}
    96  
    97  			return
    98  		}, nil
    99  
   100  	default:
   101  		return nil, ErrFuncNotSupported
   102  	}
   103  }