You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

179 lines
3.6 KiB

package types
import (
"fmt"
"maps"
"sig-pub/pkg/utils/codec"
"time"
"github.com/spf13/cast"
)
const (
inputCacheKey = "__$cache__"
)
// TODO 将indicator meta的定义的输入参数传入, 限制只能获取这些输入参数
type Input map[string]any
// getCache 避免多线程读写cache map
func (in Input) getCache(k string) (r any, ok bool) {
if in == nil {
return
}
c, ok := in[inputCacheKey]
if !ok {
return
}
r, ok = c.(map[string]any)[k]
return
}
func (in Input) setCache(k string, v any) {
if in == nil {
return
}
c, ok := in[inputCacheKey]
if !ok {
c = make(map[string]any, 4)
in[inputCacheKey] = c
}
c.(map[string]any)[k] = v
}
func (in Input) get(k string, t string) (r any) {
if in == nil {
panic(fmt.Errorf("input %s type %s not provide", k, t))
}
r, ok := in[k]
if !ok {
panic(fmt.Errorf("input %s type %s not provide", k, t))
}
return
}
func (in Input) Float(k string) (v float64) {
if r, ok := in.getCache(k); ok {
if v, ok = r.(float64); ok {
return
}
}
v, err := cast.ToFloat64E(in.get(k, "float"))
if err != nil {
panic(fmt.Errorf("input float parse error: %s", k))
}
in.setCache(k, v)
return
}
func (in Input) Int(k string) (v int) {
if r, ok := in.getCache(k); ok {
if v, ok = r.(int); ok {
return
}
}
v, err := cast.ToIntE(in.get(k, "int"))
if err != nil {
panic(fmt.Errorf("input int parse error: %s", k))
}
in.setCache(k, v)
return
}
func (in Input) Int16(k string) (v int16) {
if r, ok := in.getCache(k); ok {
if v, ok = r.(int16); ok {
return
}
}
v, err := cast.ToInt16E(in.get(k, "int16"))
if err != nil {
panic(fmt.Errorf("input int16 parse error: %s", k))
}
in.setCache(k, v)
return
}
func (in Input) String(k string) (v string) {
if k == "pt" && in != nil {
if _, ok := in[k]; !ok {
in[k] = KPriceTypeDefault
}
}
v, err := cast.ToStringE(in.get(k, "string"))
if err != nil {
panic(fmt.Errorf("input string parse error: %s", k))
}
return
}
func (in Input) Time(k string) (v time.Time) {
v, err := cast.ToTimeInDefaultLocationE(in.get(k, "time"), time.Local)
if err != nil {
panic(fmt.Errorf("input time parse error: %s", k))
}
return
}
func (in Input) PriceType(k ...string) (v KPriceType) {
key := "pt"
if len(k) > 0 {
key = k[0]
}
v = KPriceType(in.String(key))
return
}
func (in Input) Decode(k string, point any) {
t := fmt.Sprintf("%T", point)
v := in.get(k, t)
if err := codec.MapDecode(v, point); err != nil {
panic(fmt.Errorf("input %s decode error: %s, %v", t, k, err))
}
}
func (in Input) DecodeInput(point any) {
if err := codec.MapDecode(in, point); err != nil {
panic(fmt.Errorf("input decode to %T error: %v", point, err))
}
}
// Assign 将other中的值赋给当前Input
func (in Input) Assign(others ...Input) Input {
for _, other := range others {
maps.Copy(in, other)
}
return in
}
// 参数类型
type InputType int8
const (
_ InputType = iota
InputTypeBool
InputTypeString
InputTypeFloat
InputTypeUFloat
InputTypeInt
InputTypeUInt
InputTypeTime
InputTypeKPriceType // K线价格类型
InputTypeUFloats // float数组
InputTypeUFloats2D // float二维数组
InputTypeSelect // 单选
InputTypeCheckBox // 多选
)
type InputArg struct {
Name string `json:"name"`
Desc string `json:"desc"`
Type InputType `json:"type"` // 参数类型
Options []InputOption `json:"options"` // 单选/多选选项列表
Default any `json:"default"` // 默认值 TODO 构造context前将默认值置入input
}
type InputOption struct {
Name string `json:"name"`
Desc string `json:"desc"`
}