-
Notifications
You must be signed in to change notification settings - Fork 1
/
module.go
104 lines (91 loc) · 1.89 KB
/
module.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package util
import (
"bytes"
"github.com/rarnu/goscript"
"github.com/rarnu/goscript/module/require"
)
const ModuleName = "node:util"
type Util struct {
runtime *goscript.Runtime
}
func (u *Util) format(f rune, val goscript.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").(*goscript.Object); ok {
if stringify, ok := goscript.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 ...goscript.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 goscript.FunctionCall) goscript.Value {
var b bytes.Buffer
var fmt string
if arg := call.Argument(0); !goscript.IsUndefined(arg) {
fmt = arg.String()
}
var args []goscript.Value
if len(call.Arguments) > 0 {
args = call.Arguments[1:]
}
u.Format(&b, fmt, args...)
return u.runtime.ToValue(b.String())
}
func Require(runtime *goscript.Runtime, module *goscript.Object) {
u := &Util{
runtime: runtime,
}
obj := module.Get("exports").(*goscript.Object)
obj.Set("format", u.js_format)
}
func New(runtime *goscript.Runtime) *Util {
return &Util{
runtime: runtime,
}
}
func init() {
require.RegisterNativeModule(ModuleName, Require)
}