This commit is contained in:
parent
dcd4d0c5d2
commit
d937ee4b54
|
@ -20,6 +20,8 @@ func main() {
|
|||
instRepl := repl.New(
|
||||
ucl.WithModule(builtins.OS()),
|
||||
ucl.WithModule(builtins.FS(nil)),
|
||||
ucl.WithModule(builtins.Log(nil)),
|
||||
ucl.WithModule(builtins.Strs()),
|
||||
)
|
||||
ctx := context.Background()
|
||||
|
||||
|
|
|
@ -21,9 +21,12 @@ func invokeUCLCallback(name string, args ...any) {
|
|||
func initJS(ctx context.Context) {
|
||||
uclObj := make(map[string]any)
|
||||
|
||||
replInst := repl.New(ucl.WithOut(ucl.LineHandler(func(line string) {
|
||||
invokeUCLCallback("onOutLine", line)
|
||||
})))
|
||||
replInst := repl.New(
|
||||
ucl.WithModule(builtins.Log(nil)),
|
||||
ucl.WithModule(builtins.Strs()),
|
||||
ucl.WithOut(ucl.LineHandler(func(line string) {
|
||||
invokeUCLCallback("onOutLine", line)
|
||||
})))
|
||||
|
||||
uclObj["eval"] = js.FuncOf(func(this js.Value, args []js.Value) any {
|
||||
if len(args) != 2 {
|
||||
|
|
44
ucl/builtins/log.go
Normal file
44
ucl/builtins/log.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package builtins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"strings"
|
||||
"ucl.lmika.dev/ucl"
|
||||
)
|
||||
|
||||
type LogMessageHandler func(s string) error
|
||||
|
||||
func Log(handler LogMessageHandler) ucl.Module {
|
||||
if handler == nil {
|
||||
handler = func(s string) error {
|
||||
log.Println(s)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
lh := logHandler{handler: handler}
|
||||
|
||||
return ucl.Module{
|
||||
Name: "log",
|
||||
Builtins: map[string]ucl.BuiltinHandler{
|
||||
"puts": lh.logMessage,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type logHandler struct {
|
||||
handler LogMessageHandler
|
||||
}
|
||||
|
||||
func (lh logHandler) logMessage(ctx context.Context, args ucl.CallArgs) (any, error) {
|
||||
var sb strings.Builder
|
||||
var s ucl.Object
|
||||
|
||||
for args.NArgs() > 0 {
|
||||
if err := args.Bind(&s); err == nil {
|
||||
sb.WriteString(s.String())
|
||||
}
|
||||
}
|
||||
return nil, lh.handler(sb.String())
|
||||
}
|
47
ucl/builtins/log_test.go
Normal file
47
ucl/builtins/log_test.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package builtins_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"ucl.lmika.dev/ucl"
|
||||
"ucl.lmika.dev/ucl/builtins"
|
||||
)
|
||||
|
||||
func TestLog_Puts(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
eval string
|
||||
want any
|
||||
wantErr bool
|
||||
wantLog string
|
||||
}{
|
||||
{desc: "log 1", eval: `log:puts "bad stuff here"`, wantLog: "bad stuff here\n"},
|
||||
{desc: "log 2", eval: `log:puts "bad " 123 " here " [1 2 3]`, wantLog: "bad 123 here [1 2 3]\n"},
|
||||
{desc: "log 3", eval: `log:puts`, wantLog: "\n"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
var logMessage bytes.Buffer
|
||||
|
||||
inst := ucl.New(
|
||||
ucl.WithModule(builtins.Log(func(s string) error {
|
||||
logMessage.WriteString(s)
|
||||
logMessage.WriteByte('\n')
|
||||
return nil
|
||||
})),
|
||||
)
|
||||
|
||||
res, err := inst.Eval(context.Background(), tt.eval)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.want, res)
|
||||
}
|
||||
assert.Equal(t, tt.wantLog, logMessage.String())
|
||||
})
|
||||
}
|
||||
}
|
|
@ -96,8 +96,12 @@ func (u userBuiltin) invoke(ctx context.Context, args invocationArgs) (Object, e
|
|||
|
||||
func (ca CallArgs) bindArg(v interface{}, arg Object) error {
|
||||
switch t := v.(type) {
|
||||
case *Object:
|
||||
*t = arg
|
||||
return nil
|
||||
case *interface{}:
|
||||
*t, _ = toGoValue(arg)
|
||||
return nil
|
||||
case *Invokable:
|
||||
i, ok := arg.(invokable)
|
||||
if !ok {
|
||||
|
@ -123,12 +127,14 @@ func (ca CallArgs) bindArg(v interface{}, arg Object) error {
|
|||
} else {
|
||||
*t = ""
|
||||
}
|
||||
return nil
|
||||
case *int:
|
||||
if iArg, ok := arg.(intObject); ok {
|
||||
*t = int(iArg)
|
||||
} else {
|
||||
return errors.New("invalid arg")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
switch t := arg.(type) {
|
||||
|
|
Loading…
Reference in a new issue