mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 16:25:16 +00:00
interact: split interaction files
This commit is contained in:
parent
97ca304bec
commit
0114d92f2f
|
@ -3,43 +3,15 @@ package interact
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/scanner"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Reply interface {
|
||||
Message(message string)
|
||||
AddButton(text string)
|
||||
RemoveKeyboard()
|
||||
}
|
||||
|
||||
// Responder defines the logic of responding the message
|
||||
type Responder func(message string, reply Reply, ctxObjects ...interface{}) error
|
||||
|
||||
type CustomInteraction interface {
|
||||
Commands(interact *Interact)
|
||||
}
|
||||
|
||||
type State string
|
||||
|
||||
const (
|
||||
StatePublic State = "public"
|
||||
StateAuthenticated State = "authenticated"
|
||||
)
|
||||
|
||||
type TextMessageResponder interface {
|
||||
SetTextMessageResponder(responder Responder)
|
||||
}
|
||||
|
||||
type CommandResponder interface {
|
||||
AddCommand(command *Command, responder Responder)
|
||||
}
|
||||
|
||||
type Messenger interface {
|
||||
TextMessageResponder
|
||||
CommandResponder
|
||||
|
@ -251,120 +223,3 @@ func (it *Interact) Start(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func parseCommand(src string) (args []string) {
|
||||
var s scanner.Scanner
|
||||
s.Init(strings.NewReader(src))
|
||||
s.Filename = "command"
|
||||
for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
|
||||
text := s.TokenText()
|
||||
if text[0] == '"' && text[len(text)-1] == '"' {
|
||||
text, _ = strconv.Unquote(text)
|
||||
}
|
||||
args = append(args, text)
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
func parseFuncArgsAndCall(f interface{}, args []string, objects ...interface{}) (State, error) {
|
||||
fv := reflect.ValueOf(f)
|
||||
ft := reflect.TypeOf(f)
|
||||
|
||||
argIndex := 0
|
||||
|
||||
var rArgs []reflect.Value
|
||||
for i := 0; i < ft.NumIn(); i++ {
|
||||
at := ft.In(i)
|
||||
|
||||
switch k := at.Kind(); k {
|
||||
|
||||
case reflect.Interface:
|
||||
found := false
|
||||
|
||||
for oi := 0; oi < len(objects); oi++ {
|
||||
obj := objects[oi]
|
||||
objT := reflect.TypeOf(obj)
|
||||
objV := reflect.ValueOf(obj)
|
||||
|
||||
fmt.Println(
|
||||
at.PkgPath(),
|
||||
at.Name(),
|
||||
objT, "implements", at, "=", objT.Implements(at),
|
||||
)
|
||||
|
||||
if objT.Implements(at) {
|
||||
found = true
|
||||
rArgs = append(rArgs, objV)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
v := reflect.Zero(at)
|
||||
rArgs = append(rArgs, v)
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
av := reflect.ValueOf(args[argIndex])
|
||||
rArgs = append(rArgs, av)
|
||||
argIndex++
|
||||
|
||||
case reflect.Bool:
|
||||
bv, err := strconv.ParseBool(args[argIndex])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
av := reflect.ValueOf(bv)
|
||||
rArgs = append(rArgs, av)
|
||||
argIndex++
|
||||
|
||||
case reflect.Int64:
|
||||
nf, err := strconv.ParseInt(args[argIndex], 10, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
av := reflect.ValueOf(nf)
|
||||
rArgs = append(rArgs, av)
|
||||
argIndex++
|
||||
|
||||
case reflect.Float64:
|
||||
nf, err := strconv.ParseFloat(args[argIndex], 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
av := reflect.ValueOf(nf)
|
||||
rArgs = append(rArgs, av)
|
||||
argIndex++
|
||||
}
|
||||
}
|
||||
|
||||
out := fv.Call(rArgs)
|
||||
if ft.NumOut() == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// try to get the error object from the return value
|
||||
var state State
|
||||
var err error
|
||||
for i := 0; i < ft.NumOut(); i++ {
|
||||
outType := ft.Out(i)
|
||||
switch outType.Kind() {
|
||||
case reflect.String:
|
||||
if outType.Name() == "State" {
|
||||
state = State(out[i].String())
|
||||
}
|
||||
|
||||
case reflect.Interface:
|
||||
o := out[i].Interface()
|
||||
switch ov := o.(type) {
|
||||
case error:
|
||||
err = ov
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return state, err
|
||||
}
|
||||
|
|
128
pkg/interact/parse.go
Normal file
128
pkg/interact/parse.go
Normal file
|
@ -0,0 +1,128 @@
|
|||
package interact
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/scanner"
|
||||
)
|
||||
|
||||
func parseFuncArgsAndCall(f interface{}, args []string, objects ...interface{}) (State, error) {
|
||||
fv := reflect.ValueOf(f)
|
||||
ft := reflect.TypeOf(f)
|
||||
|
||||
argIndex := 0
|
||||
|
||||
var rArgs []reflect.Value
|
||||
for i := 0; i < ft.NumIn(); i++ {
|
||||
at := ft.In(i)
|
||||
|
||||
switch k := at.Kind(); k {
|
||||
|
||||
case reflect.Interface:
|
||||
found := false
|
||||
|
||||
for oi := 0; oi < len(objects); oi++ {
|
||||
obj := objects[oi]
|
||||
objT := reflect.TypeOf(obj)
|
||||
objV := reflect.ValueOf(obj)
|
||||
|
||||
fmt.Println(
|
||||
at.PkgPath(),
|
||||
at.Name(),
|
||||
objT, "implements", at, "=", objT.Implements(at),
|
||||
)
|
||||
|
||||
if objT.Implements(at) {
|
||||
found = true
|
||||
rArgs = append(rArgs, objV)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
v := reflect.Zero(at)
|
||||
rArgs = append(rArgs, v)
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
av := reflect.ValueOf(args[argIndex])
|
||||
rArgs = append(rArgs, av)
|
||||
argIndex++
|
||||
|
||||
case reflect.Bool:
|
||||
bv, err := strconv.ParseBool(args[argIndex])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
av := reflect.ValueOf(bv)
|
||||
rArgs = append(rArgs, av)
|
||||
argIndex++
|
||||
|
||||
case reflect.Int64:
|
||||
nf, err := strconv.ParseInt(args[argIndex], 10, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
av := reflect.ValueOf(nf)
|
||||
rArgs = append(rArgs, av)
|
||||
argIndex++
|
||||
|
||||
case reflect.Float64:
|
||||
nf, err := strconv.ParseFloat(args[argIndex], 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
av := reflect.ValueOf(nf)
|
||||
rArgs = append(rArgs, av)
|
||||
argIndex++
|
||||
}
|
||||
}
|
||||
|
||||
out := fv.Call(rArgs)
|
||||
if ft.NumOut() == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// try to get the error object from the return value
|
||||
var state State
|
||||
var err error
|
||||
for i := 0; i < ft.NumOut(); i++ {
|
||||
outType := ft.Out(i)
|
||||
switch outType.Kind() {
|
||||
case reflect.String:
|
||||
if outType.Name() == "State" {
|
||||
state = State(out[i].String())
|
||||
}
|
||||
|
||||
case reflect.Interface:
|
||||
o := out[i].Interface()
|
||||
switch ov := o.(type) {
|
||||
case error:
|
||||
err = ov
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return state, err
|
||||
}
|
||||
|
||||
func parseCommand(src string) (args []string) {
|
||||
var s scanner.Scanner
|
||||
s.Init(strings.NewReader(src))
|
||||
s.Filename = "command"
|
||||
for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
|
||||
text := s.TokenText()
|
||||
if text[0] == '"' && text[len(text)-1] == '"' {
|
||||
text, _ = strconv.Unquote(text)
|
||||
}
|
||||
args = append(args, text)
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
7
pkg/interact/reply.go
Normal file
7
pkg/interact/reply.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package interact
|
||||
|
||||
type Reply interface {
|
||||
Message(message string)
|
||||
AddButton(text string)
|
||||
RemoveKeyboard()
|
||||
}
|
12
pkg/interact/responder.go
Normal file
12
pkg/interact/responder.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package interact
|
||||
|
||||
// Responder defines the logic of responding the message
|
||||
type Responder func(message string, reply Reply, ctxObjects ...interface{}) error
|
||||
|
||||
type TextMessageResponder interface {
|
||||
SetTextMessageResponder(responder Responder)
|
||||
}
|
||||
|
||||
type CommandResponder interface {
|
||||
AddCommand(command *Command, responder Responder)
|
||||
}
|
8
pkg/interact/state.go
Normal file
8
pkg/interact/state.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package interact
|
||||
|
||||
type State string
|
||||
|
||||
const (
|
||||
StatePublic State = "public"
|
||||
StateAuthenticated State = "authenticated"
|
||||
)
|
Loading…
Reference in New Issue
Block a user