105 lines
1.8 KiB
Go
105 lines
1.8 KiB
Go
|
package util
|
||
|
|
||
|
import (
|
||
|
"apigo.cc/ai/ai/goja"
|
||
|
"apigo.cc/ai/ai/goja_nodejs/require"
|
||
|
"bytes"
|
||
|
)
|
||
|
|
||
|
const ModuleName = "util"
|
||
|
|
||
|
type Util struct {
|
||
|
runtime *goja.Runtime
|
||
|
}
|
||
|
|
||
|
func (u *Util) format(f rune, val goja.Value, w *bytes.Buffer) bool {
|
||
|
switch f {
|
||
|
case 's':
|
||
|
w.WriteString(val.String())
|
||
|
case 'd':
|
||
|
w.WriteString(val.ToNumber().String())
|
||
|
case 'j':
|
||
|
if json, ok := u.runtime.Get("JSON").(*goja.Object); ok {
|
||
|
if stringify, ok := goja.AssertFunction(json.Get("stringify")); ok {
|
||
|
res, err := stringify(json, val)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
w.WriteString(res.String())
|
||
|
}
|
||
|
}
|
||
|
case '%':
|
||
|
w.WriteByte('%')
|
||
|
return false
|
||
|
default:
|
||
|
w.WriteByte('%')
|
||
|
w.WriteRune(f)
|
||
|
return false
|
||
|
}
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func (u *Util) Format(b *bytes.Buffer, f string, args ...goja.Value) {
|
||
|
pct := false
|
||
|
argNum := 0
|
||
|
for _, chr := range f {
|
||
|
if pct {
|
||
|
if argNum < len(args) {
|
||
|
if u.format(chr, args[argNum], b) {
|
||
|
argNum++
|
||
|
}
|
||
|
} else {
|
||
|
b.WriteByte('%')
|
||
|
b.WriteRune(chr)
|
||
|
}
|
||
|
pct = false
|
||
|
} else {
|
||
|
if chr == '%' {
|
||
|
pct = true
|
||
|
} else {
|
||
|
b.WriteRune(chr)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for _, arg := range args[argNum:] {
|
||
|
b.WriteByte(' ')
|
||
|
b.WriteString(arg.String())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (u *Util) js_format(call goja.FunctionCall) goja.Value {
|
||
|
var b bytes.Buffer
|
||
|
var fmt string
|
||
|
|
||
|
if arg := call.Argument(0); !goja.IsUndefined(arg) {
|
||
|
fmt = arg.String()
|
||
|
}
|
||
|
|
||
|
var args []goja.Value
|
||
|
if len(call.Arguments) > 0 {
|
||
|
args = call.Arguments[1:]
|
||
|
}
|
||
|
u.Format(&b, fmt, args...)
|
||
|
|
||
|
return u.runtime.ToValue(b.String())
|
||
|
}
|
||
|
|
||
|
func Require(runtime *goja.Runtime, module *goja.Object) {
|
||
|
u := &Util{
|
||
|
runtime: runtime,
|
||
|
}
|
||
|
obj := module.Get("exports").(*goja.Object)
|
||
|
obj.Set("format", u.js_format)
|
||
|
}
|
||
|
|
||
|
func New(runtime *goja.Runtime) *Util {
|
||
|
return &Util{
|
||
|
runtime: runtime,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func init() {
|
||
|
require.RegisterCoreModule(ModuleName, Require)
|
||
|
}
|