package cli import ( "fmt" "io" "math" ) type Context struct { Id int64 seq uint16 wc io.WriteCloser params map[string]string args []string } func (ctx *Context) reset(id int64, wc io.WriteCloser) { ctx.Id = id ctx.wc = wc ctx.seq = 0 ctx.args = make([]string, 0) ctx.params = make(map[string]string) } func (ctx *Context) setArgs(args []string) { ctx.args = args } func (ctx *Context) setParam(ps map[string]string) { ctx.params = ps } func (ctx *Context) Bind(v any) (err error) { return } func (ctx *Context) Argument(index int) string { if index >= len(ctx.args) || index < 0 { return "" } return ctx.args[index] } func (ctx *Context) Param(s string) string { if v, ok := ctx.params[s]; ok { return v } return "" } func (ctx *Context) Success(v any) (err error) { return ctx.send(responsePayload{Type: PacketTypeCommand, Data: v}) } func (ctx *Context) Error(code int, reason string) (err error) { return ctx.send(responsePayload{Type: PacketTypeCommand, Code: code, Reason: reason}) } func (ctx *Context) Close() (err error) { return ctx.wc.Close() } func (ctx *Context) send(res responsePayload) (err error) { var ( ok bool buf []byte marshal encoder ) if res.Code > 0 { err = writeFrame(ctx.wc, &Frame{ Feature: Feature, Type: res.Type, Seq: ctx.seq, Flag: FlagComplete, Error: fmt.Sprintf("ERROR(%d): %s", res.Code, res.Reason), }) return } if res.Data == nil { buf = OK goto __END } if marshal, ok = res.Data.(encoder); ok { buf, err = marshal.Marshal() goto __END } buf, err = serialize(res.Data) __END: if err != nil { return } offset := 0 chunkSize := math.MaxInt16 - 1 n := len(buf) / chunkSize for i := 0; i < n; i++ { if err = writeFrame(ctx.wc, newFrame(res.Type, FlagPortion, ctx.seq, buf[offset:chunkSize+offset])); err != nil { return } offset += chunkSize } err = writeFrame(ctx.wc, newFrame(res.Type, FlagComplete, ctx.seq, buf[offset:])) return } func newContext(id int64, wc io.WriteCloser) *Context { return &Context{ Id: id, wc: wc, } }