From 266aef3c4bbcb0264b55a66cf55dbfbe7734f27f Mon Sep 17 00:00:00 2001 From: Sydonian <794346190@qq.com> Date: Tue, 30 May 2023 15:49:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E6=89=80=E6=9C=89=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E9=83=BD=E4=BD=BF=E7=94=A8cmdtrie=E6=9D=A5=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/cmdtrie/command_trie.go | 41 +++++++++++++++++++++++++------- pkg/cmdtrie/command_trie_test.go | 36 +++++++++++++++++++++------- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/pkg/cmdtrie/command_trie.go b/pkg/cmdtrie/command_trie.go index a3a2339..35333bb 100644 --- a/pkg/cmdtrie/command_trie.go +++ b/pkg/cmdtrie/command_trie.go @@ -8,6 +8,10 @@ import ( myreflect "gitlink.org.cn/cloudream/common/utils/reflect" ) +type ExecuteOption struct { + ReplaceEmptyArrayWithNil bool // 如果最后一个参数是空数组,则调用命令的时候传递nil参数 +} + type command struct { fn reflect.Value fnType reflect.Type @@ -139,7 +143,7 @@ func (t *anyCommandTrie) checkFnArgs(typ reflect.Type) error { return nil } -func (t *anyCommandTrie) Execute(ctx any, cmdWords ...string) ([]reflect.Value, error) { +func (t *anyCommandTrie) Execute(ctx any, cmdWords []string, opt ExecuteOption) ([]reflect.Value, error) { var cmd *command var argWords []string @@ -171,7 +175,7 @@ func (t *anyCommandTrie) Execute(ctx any, cmdWords ...string) ([]reflect.Value, } // 解析最后一个参数 - callArgs, err = t.parseLastArg(cmd, argWords, callArgs) + callArgs, err = t.parseLastArg(cmd, argWords, opt, callArgs) if err != nil { return nil, err } @@ -219,7 +223,7 @@ func (t *anyCommandTrie) parseFrontArgs(cmd *command, argWords []string, callArg return callArgs, nil } -func (t *anyCommandTrie) parseLastArg(cmd *command, argWords []string, callArgs []reflect.Value) ([]reflect.Value, error) { +func (t *anyCommandTrie) parseLastArg(cmd *command, argWords []string, opt ExecuteOption, callArgs []reflect.Value) ([]reflect.Value, error) { if len(cmd.staticArgTypes) > 0 { lastArgType := cmd.staticArgTypes[len(cmd.staticArgTypes)-1] lastArgWords := argWords[len(cmd.staticArgTypes)-1:] @@ -241,6 +245,10 @@ func (t *anyCommandTrie) parseLastArg(cmd *command, argWords []string, callArgs lastArg.Index(i).Set(eleVal) } + if opt.ReplaceEmptyArrayWithNil && lastArg.Len() == 0 { + lastArg = reflect.Zero(lastArgType) + } + } else { if len(lastArgWords) == 0 { return nil, fmt.Errorf("no enough arguments for command") @@ -325,8 +333,13 @@ func (t *CommandTrie[TCtx, TRet]) MustAdd(fn any, prefixWords ...string) { } } -func (t *CommandTrie[TCtx, TRet]) Execute(ctx TCtx, cmdWords ...string) (TRet, error) { - retValues, err := t.anyTrie.Execute(ctx, cmdWords...) +func (t *CommandTrie[TCtx, TRet]) Execute(ctx TCtx, cmdWords []string, opts ...ExecuteOption) (TRet, error) { + opt := ExecuteOption{} + if len(opts) > 0 { + opt = opts[0] + } + + retValues, err := t.anyTrie.Execute(ctx, cmdWords, opt) if err != nil { var defRet TRet return defRet, err @@ -361,8 +374,13 @@ func (t *VoidCommandTrie[TCtx]) MustAdd(fn any, prefixWords ...string) { } } -func (t *VoidCommandTrie[TCtx]) Execute(ctx TCtx, cmdWords ...string) error { - _, err := t.anyTrie.Execute(ctx, cmdWords...) +func (t *VoidCommandTrie[TCtx]) Execute(ctx TCtx, cmdWords []string, opts ...ExecuteOption) error { + opt := ExecuteOption{} + if len(opts) > 0 { + opt = opts[0] + } + + _, err := t.anyTrie.Execute(ctx, cmdWords, opt) return err } @@ -387,8 +405,13 @@ func (t *StaticCommandTrie[TRet]) MustAdd(fn any, prefixWords ...string) { } } -func (t *StaticCommandTrie[TRet]) Execute(cmdWords ...string) (TRet, error) { - retValues, err := t.anyTrie.Execute(nil, cmdWords...) +func (t *StaticCommandTrie[TRet]) Execute(cmdWords []string, opts ...ExecuteOption) (TRet, error) { + opt := ExecuteOption{} + if len(opts) > 0 { + opt = opts[0] + } + + retValues, err := t.anyTrie.Execute(nil, cmdWords, opt) if err != nil { var defRet TRet return defRet, err diff --git a/pkg/cmdtrie/command_trie_test.go b/pkg/cmdtrie/command_trie_test.go index 6417ee5..2edf073 100644 --- a/pkg/cmdtrie/command_trie_test.go +++ b/pkg/cmdtrie/command_trie_test.go @@ -17,7 +17,7 @@ func Test_CommandTrie(t *testing.T) { }, "a") So(err, ShouldBeNil) - err = trie.Execute(0, "a") + err = trie.Execute(0, []string{"a"}) So(err, ShouldBeNil) So(ret, ShouldEqual, "ok") @@ -40,7 +40,7 @@ func Test_CommandTrie(t *testing.T) { }, "a", "b") So(err, ShouldBeNil) - err = trie.Execute(0, "a", "b", "1", "2", "true", "3") + err = trie.Execute(0, []string{"a", "b", "1", "2", "true", "3"}) So(err, ShouldBeNil) So(argI, ShouldEqual, 1) @@ -62,7 +62,7 @@ func Test_CommandTrie(t *testing.T) { }, "a", "b") So(err, ShouldBeNil) - err = trie.Execute(0, "a", "b", "1", "2", "3", "4") + err = trie.Execute(0, []string{"a", "b", "1", "2", "3", "4"}) So(err, ShouldBeNil) So(argI, ShouldEqual, 1) @@ -82,7 +82,7 @@ func Test_CommandTrie(t *testing.T) { }, "a", "b") So(err, ShouldBeNil) - err = trie.Execute(0, "a", "b", "1") + err = trie.Execute(0, []string{"a", "b", "1"}) So(err, ShouldBeNil) So(argI, ShouldEqual, 1) @@ -102,7 +102,7 @@ func Test_CommandTrie(t *testing.T) { }, "a", "b") So(err, ShouldBeNil) - ret, err := trie.Execute(0, "a", "b", "1") + ret, err := trie.Execute(0, []string{"a", "b", "1"}) So(err, ShouldBeNil) So(argI, ShouldEqual, 1) @@ -128,13 +128,13 @@ func Test_CommandTrie(t *testing.T) { }, "a", "c") So(err, ShouldBeNil) - ret, err := trie.Execute(0, "a", "b", "1") + ret, err := trie.Execute(0, []string{"a", "b", "1"}) So(err, ShouldBeNil) So(argI, ShouldEqual, 1) So(argArr, ShouldResemble, []int64{}) So(ret, ShouldEqual, 123) - ret2, err := trie.Execute(0, "a", "c", "1") + ret2, err := trie.Execute(0, []string{"a", "c", "1"}) So(err, ShouldBeNil) So(ret2, ShouldEqual, "123") }) @@ -152,7 +152,7 @@ func Test_CommandTrie(t *testing.T) { }, "a", "b") So(err, ShouldBeNil) - ret, err := trie.Execute("a", "b", "1") + ret, err := trie.Execute([]string{"a", "b", "1"}) So(err, ShouldBeNil) So(argI, ShouldEqual, 1) @@ -173,11 +173,29 @@ func Test_CommandTrie(t *testing.T) { }, "a", "b") So(err, ShouldBeNil) - ret, err := trie.Execute("a", "b") + ret, err := trie.Execute([]string{"a", "b"}) So(err, ShouldBeNil) So(argI, ShouldEqual, 1) So(argArr, ShouldResemble, []int64{}) So(ret, ShouldEqual, 123) }) + + Convey("空数组参数变成nil", t, func() { + trie := NewStaticCommandTrie[int]() + + var argStrs []string + + err := trie.Add(func(strs []string) int { + argStrs = strs + return 123 + }, "a", "b") + So(err, ShouldBeNil) + + ret, err := trie.Execute([]string{"a", "b"}, ExecuteOption{ReplaceEmptyArrayWithNil: true}) + So(err, ShouldBeNil) + + So(argStrs, ShouldBeNil) + So(ret, ShouldEqual, 123) + }) }