276 lines
4.8 KiB
Go
276 lines
4.8 KiB
Go
package pipe
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/yaoapp/kun/log"
|
|
"github.com/yaoapp/kun/utils"
|
|
"github.com/yaoapp/yao/pipe/ui/cli"
|
|
)
|
|
|
|
// ExecProcess Execute the process
|
|
func (node Node) ExecProcess(ctx *Context, args []any) error {
|
|
var err error
|
|
name := node.Namespace()
|
|
ctx.in[name] = args
|
|
if node.Input != nil {
|
|
ctx.in[name], err = ctx.replaceInput(node.Input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
ctx.input[name] = ctx.in[name]
|
|
res := true
|
|
|
|
ctx.out[name] = res
|
|
ctx.output[name] = res
|
|
if node.Output != nil {
|
|
ctx.output[name], err = ctx.replace(node.Output)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
next, err := ctx.Next()
|
|
if err != nil {
|
|
if IsEOF(err) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
// Execute the next node
|
|
_, err = ctx.exec(next, ctx.output[name])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ExecRequest Execute the request
|
|
func (node Node) ExecRequest(ctx *Context, args []any) error {
|
|
return nil
|
|
}
|
|
|
|
// ExecAI Execute the AI
|
|
func (node Node) ExecAI(ctx *Context, args []any) error {
|
|
var err error
|
|
name := node.Namespace()
|
|
ctx.in[name] = args
|
|
if node.Input != nil {
|
|
ctx.in[name], err = ctx.replaceInput(node.Input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
ctx.input[name] = ctx.in[name]
|
|
|
|
res := map[string]any{"args": args, "Chinese": "你好", "Arabic": "مرحبا"}
|
|
ctx.out[name] = res
|
|
ctx.output[name] = res
|
|
if node.Output != nil {
|
|
ctx.output[name], err = ctx.replace(node.Output)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
next, err := ctx.Next()
|
|
if err != nil {
|
|
if IsEOF(err) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
// Execute the next node
|
|
_, err = ctx.exec(next, ctx.output[name])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ExecSwitch Execute the switch
|
|
func (node Node) ExecSwitch(ctx *Context, args []any) error {
|
|
var err error
|
|
name := node.Namespace()
|
|
|
|
ctx.in[name] = args
|
|
if node.Input != nil {
|
|
ctx.in[name], err = ctx.replaceInput(node.Input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
ctx.input[name] = ctx.in[name]
|
|
|
|
data, err := ctx.data()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
section, _ := node.Case["default"]
|
|
for stmt := range node.Case {
|
|
if stmt == "default" {
|
|
continue
|
|
}
|
|
|
|
v, err := data.Exec(stmt)
|
|
if err != nil {
|
|
log.Warn("pipe: %s %s", ctx.Name, err)
|
|
continue
|
|
}
|
|
|
|
// If the result is true, then break the loop
|
|
if match, ok := v.(bool); ok && match {
|
|
section = node.Case[stmt]
|
|
break
|
|
}
|
|
}
|
|
|
|
// Execute the next node
|
|
if section == nil {
|
|
return fmt.Errorf("pipe: %s %s", ctx.Name, "node case not matched")
|
|
}
|
|
|
|
// Execute The Pipe
|
|
subCtx := section.Create().
|
|
With(ctx.context).
|
|
WithGlobal(ctx.global).
|
|
WithSid(ctx.sid)
|
|
|
|
// Copy the input and output
|
|
for k, v := range ctx.in {
|
|
subCtx.in[k] = v
|
|
}
|
|
|
|
for k, v := range ctx.input {
|
|
subCtx.input[k] = v
|
|
}
|
|
|
|
for k, v := range ctx.out {
|
|
subCtx.out[k] = v
|
|
}
|
|
|
|
for k, v := range ctx.output {
|
|
subCtx.output[k] = v
|
|
}
|
|
|
|
_, err = subCtx.Exec(ctx.in[name])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Merge the output
|
|
for k, v := range subCtx.out {
|
|
ctx.out[k] = v
|
|
}
|
|
|
|
for k, v := range subCtx.output {
|
|
ctx.output[k] = v
|
|
}
|
|
|
|
utils.Dump(name, ctx.output)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Render Execute the user input
|
|
func (node Node) Render(ctx *Context, args []any) error {
|
|
|
|
switch node.UI {
|
|
|
|
case "cli":
|
|
return node.renderCli(ctx, args)
|
|
|
|
case "web":
|
|
|
|
default:
|
|
return fmt.Errorf("pipe: %s %s", ctx.Name, "node ui not supported")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Namespace the node namespace
|
|
func (node Node) Namespace() string {
|
|
name := node.Name
|
|
if node.namespace != "" {
|
|
name = fmt.Sprintf("%s.%s", node.namespace, name)
|
|
}
|
|
return name
|
|
}
|
|
|
|
func (node Node) renderCli(ctx *Context, args []any) error {
|
|
|
|
var err error
|
|
name := node.Namespace()
|
|
|
|
ctx.in[name] = args
|
|
if node.Input != nil {
|
|
ctx.in[name], err = ctx.replaceInput(node.Input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
ctx.input[name] = ctx.in[name]
|
|
|
|
// Set option
|
|
label, err := ctx.replaceString(node.Label)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
option := &cli.Option{Label: label}
|
|
if node.AutoFill != nil {
|
|
|
|
value := fmt.Sprintf("%v", node.AutoFill.Value)
|
|
value, err = ctx.replaceString(value)
|
|
if value != "" {
|
|
if err != nil {
|
|
fmt.Println("cmd", err)
|
|
return err
|
|
}
|
|
|
|
if node.AutoFill.Action == "exit" {
|
|
value = fmt.Sprintf("%s\nexit()\n", value)
|
|
}
|
|
option.Reader = strings.NewReader(value)
|
|
}
|
|
}
|
|
|
|
userDataLines, err := cli.New(option).Render(args)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx.out[name] = userDataLines
|
|
ctx.output[name] = userDataLines
|
|
if node.Output != nil {
|
|
ctx.output[name], err = ctx.replace(node.Output)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Execute the next node
|
|
next, err := ctx.Next()
|
|
if err != nil {
|
|
if IsEOF(err) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
// Execute the next node
|
|
_, err = ctx.exec(next, ctx.output[name])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Next node
|
|
return nil
|
|
}
|