github.com/iosif02/goja_nodejs@v1.0.1/util/module.go (about)

     1  package util
     2  
     3  import (
     4  	"bytes"
     5  	"github.com/iosif02/goja"
     6  	"github.com/iosif02/goja_nodejs/require"
     7  )
     8  
     9  const ModuleName = "util"
    10  
    11  type Util struct {
    12  	runtime *goja.Runtime
    13  }
    14  
    15  func (u *Util) format(f rune, val goja.Value, w *bytes.Buffer) bool {
    16  	switch f {
    17  	case 's':
    18  		w.WriteString(val.String())
    19  	case 'd':
    20  		w.WriteString(val.ToNumber().String())
    21  	case 'j':
    22  		if json, ok := u.runtime.Get("JSON").(*goja.Object); ok {
    23  			if stringify, ok := goja.AssertFunction(json.Get("stringify")); ok {
    24  				res, err := stringify(json, val)
    25  				if err != nil {
    26  					panic(err)
    27  				}
    28  				w.WriteString(res.String())
    29  			}
    30  		}
    31  	case '%':
    32  		w.WriteByte('%')
    33  		return false
    34  	default:
    35  		w.WriteByte('%')
    36  		w.WriteRune(f)
    37  		return false
    38  	}
    39  	return true
    40  }
    41  
    42  func (u *Util) Format(b *bytes.Buffer, f string, args ...goja.Value) {
    43  	pct := false
    44  	argNum := 0
    45  	for _, chr := range f {
    46  		if pct {
    47  			if argNum < len(args) {
    48  				if u.format(chr, args[argNum], b) {
    49  					argNum++
    50  				}
    51  			} else {
    52  				b.WriteByte('%')
    53  				b.WriteRune(chr)
    54  			}
    55  			pct = false
    56  		} else {
    57  			if chr == '%' {
    58  				pct = true
    59  			} else {
    60  				b.WriteRune(chr)
    61  			}
    62  		}
    63  	}
    64  
    65  	for _, arg := range args[argNum:] {
    66  		b.WriteByte(' ')
    67  		b.WriteString(arg.String())
    68  	}
    69  }
    70  
    71  func (u *Util) js_format(call goja.FunctionCall) goja.Value {
    72  	var b bytes.Buffer
    73  	var fmt string
    74  
    75  	if arg := call.Argument(0); !goja.IsUndefined(arg) {
    76  		fmt = arg.String()
    77  	}
    78  
    79  	var args []goja.Value
    80  	if len(call.Arguments) > 0 {
    81  		args = call.Arguments[1:]
    82  	}
    83  	u.Format(&b, fmt, args...)
    84  
    85  	return u.runtime.ToValue(b.String())
    86  }
    87  
    88  func Require(runtime *goja.Runtime, module *goja.Object) {
    89  	u := &Util{
    90  		runtime: runtime,
    91  	}
    92  	obj := module.Get("exports").(*goja.Object)
    93  	obj.Set("format", u.js_format)
    94  }
    95  
    96  func New(runtime *goja.Runtime) *Util {
    97  	return &Util{
    98  		runtime: runtime,
    99  	}
   100  }
   101  
   102  func init() {
   103  	require.RegisterCoreModule(ModuleName, Require)
   104  }