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
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] = PriceTypeDefault |
|
} |
|
} |
|
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 PriceType) { |
|
key := "pt" |
|
if len(k) > 0 { |
|
key = k[0] |
|
} |
|
v = PriceType(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 |
|
InputTypePriceType // 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"` |
|
}
|
|
|