From 96a125e4857847ea52a13d644e8ef376bedbcec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Sat, 12 Oct 2024 23:54:15 +0900 Subject: [PATCH 1/4] fix(ci): make lint happy --- .golangci.yml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 03dca4b..c74a2ce 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -13,42 +13,38 @@ linters: fast: false enable: - bodyclose - #- deadcode #- depguard - dogsled - - dupl - errcheck - exportloopref - exhaustive #- funlen #- goconst - #- gocritic + - gocritic #- gocyclo - - gofumpt + - gofmt - goimports - goprintffuncname #- gosec - gosimple - govet - ineffassign - - misspell + #- misspell - nolintlint - rowserrcheck - staticcheck - #- structcheck - #- stylecheck + - stylecheck - typecheck - unconvert - unparam - unused - #- varcheck - whitespace - prealloc - predeclared - asciicheck - #- revive + - revive + - forbidigo - makezero - #- interfacer run: @@ -57,6 +53,7 @@ run: deadline: 5m issues-exit-code: 1 tests: false + go: '1.20' # output configuration options output: From a3cc6ddc3fda4a8583bf6c1bde491b1aae3bea2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Sun, 13 Oct 2024 00:09:58 +0900 Subject: [PATCH 2/4] chore: make lint happy --- .github/workflows/go-vet.yml | 4 +- all_test.go | 2 +- api.go | 16 ++--- bot.go | 24 +++---- context.go | 8 +-- docs/content/start/install.md | 2 +- driver/wsclient.go | 18 ++--- driver/wsserver.go | 18 ++--- event_channel.go | 12 ++-- example/manager/rule.go | 2 +- example/music/main.go | 2 +- example/shell/shell.go | 10 +-- extension/filter/filter.go | 34 +++++----- extension/filter/filter_test.go | 6 +- message/cqcode.go | 5 +- message/cqstring.go | 2 +- message/cqstring_test.go | 10 +-- message/message.go | 114 ++++++++++++++++---------------- message/message_test.go | 2 +- ring_test.go | 3 +- rules.go | 12 ++-- types.go | 2 +- utils/async/async.go | 36 +++++----- 23 files changed, 171 insertions(+), 173 deletions(-) diff --git a/.github/workflows/go-vet.yml b/.github/workflows/go-vet.yml index d6355c3..ed30d12 100644 --- a/.github/workflows/go-vet.yml +++ b/.github/workflows/go-vet.yml @@ -11,7 +11,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@master with: - go-version: ^1.20 + go-version: "1.20" - name: Check out code into the Go module directory uses: actions/checkout@master @@ -32,7 +32,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@master with: - go-version: ^1.20 + go-version: "1.20" - name: Check out code into the Go module directory uses: actions/checkout@master diff --git a/all_test.go b/all_test.go index 296a81b..b28d6fa 100644 --- a/all_test.go +++ b/all_test.go @@ -67,6 +67,6 @@ func TestMatcher_Delete(t *testing.T) { const base64Image = `base64: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t2Xk27fMnxjjOc5/SuonumsdLe7uo2doYS8qW6FySBkhR1PtQBNBNHc28c8Lbo5VDo2MZBGQakqOCUTwRzKrqsihgHUqwyM8g9D7VJQByuoXPjRdQ00Q2OmiNrhhL5d1IylfKkI3nyvlG4LyO+0d6Dc+NP7fCfYNN8j7KTj7VJ5W7eP4vKzux29Ki8aeGNBHhnWb8aPZC7+zyy+f5C79+Cd2cZznnNQeKfDvhax0eZbfTNNt712jSDZEiybmdQNvfPNAGxqeoa5C2mW9nYRy3crGS6VHIhWNRyBIy9SzLjjOM+lVPDWta5d6bJPfafGY0mugZ/tIJGyWQBdoUdNoXOe2am8WQQ3E+l250uzvp7md4YzdsVWMeWzk5AJ58vFcp4dsVsILVptF01ftN3fRJcRSMZI2Rp26FQMfIVHPTFAHW2GsXN/q2iMT5cN9pEt3JCORv3QY568CRh+NUbfxPrEhtZpreyW2vHuUj2Fy6mIOQTnjnZ+tJoH/IQ8K/9i7J/O1rJtLy1ls9Gto7mF5459QLxK4LL8s3UdRQBei1XxPLFG/8AaliN+lf2hj7AeDx8n+s9+tddplw93pVpcyY3zQJI2BxkqCa5PSPDGoXmjWF0fEEqGbS47faLWPAjZQcf/XrqbOWys9GgK3kTWsESp55cbcKNuSenagC7RTI5I5o1kidXRxlWU5BHqDT6ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAKGp2d9erHHaam9gnPmtFErSMO20tkL37H8KrReFdGSymtZbMXIuCGnluWMksrDoS55yO2OnbFbFFAGVp2j3Wm3IEesXVxZBSBbXWJGU9sSfex/vFvrTZdFuftt7d2epvaSXjxsSsKvtCKVx82RznP4Vr0UAc4vhvVE1GXUF8S3HnywpC5+yxYKoWK8Y9Xat20imhtkjuLg3Mqj5pWQKW/AcCpqKACiiigCjrWnDWNFvNNMvki6haLzNu7bkYzjvUz2FnJdrdvaQNcIMLM0YLgezdasUUAVbmwhu7qzuZN2+ylaWLB4yUZDn8HNZum+GILGa3nluZp5Laa4liXO2NTLJIxO3uwEhXPp2FblFAGPZ6PeprS6pqGopdPFbvBEkdv5QVXZGYn5jk/u19O9SxeHNIhRFisY0KGQq4+8C+d3PXncevrWnRQBz1roOuWNlDZW/iQCGCMRRl7FCwUDAyc4Jx7VPJ4dRdEsdOtZwpsGR4nnj8xXZc8uuRnOSeCOcEdK2qKAKOj6d/ZWni2MqyMZJJGZU2Ludyx2rk4GW4GT9TV6iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/2Q==` func TestFormatMessage_Base64(t *testing.T) { - msg := formatMessage([]message.MessageSegment{message.Image(base64Image)}) + msg := formatMessage([]message.Segment{message.Image(base64Image)}) assert.Equal(t, `[{"type":"image","data":{"file":"de8a73807aebf36d8cb25f0f6065d73e.image"}}]`, msg) } diff --git a/api.go b/api.go index a31f6be..13c983b 100644 --- a/api.go +++ b/api.go @@ -55,7 +55,7 @@ func (ctx *Ctx) CallAction(action string, params Params) APIResponse { Action: action, Params: params, } - rsp, err := ctx.caller.CallApi(req) + rsp, err := ctx.caller.CallAPI(req) if err != nil { log.Errorln("[api] 调用", action, "时出现错误: ", err) } @@ -113,7 +113,7 @@ func (ctx *Ctx) GetMessage(messageID interface{}) Message { }).Data m := Message{ Elements: message.ParseMessage(helper.StringToBytes(rsp.Get("message").Raw)), - MessageId: message.NewMessageIDFromInteger(rsp.Get("message_id").Int()), + MessageID: message.NewMessageIDFromInteger(rsp.Get("message_id").Int()), MessageType: rsp.Get("message_type").String(), Sender: &User{}, } @@ -247,7 +247,7 @@ func (ctx *Ctx) SetGroupName(groupID int64, groupName string) { // SetThisGroupName 设置本群名 // https://github.com/botuniverse/onebot-11/blob/master/api/public.md#set_group_name-%E8%AE%BE%E7%BD%AE%E7%BE%A4%E5%90%8D -func (ctx *Ctx) SetThisGroupName(groupID int64, groupName string) { +func (ctx *Ctx) SetThisGroupName(groupName string) { ctx.SetGroupName(ctx.Event.GroupID, groupName) } @@ -682,9 +682,9 @@ func (ctx *Ctx) GetThisGroupFilesByFolder(folderID string) gjson.Result { return ctx.GetGroupFilesByFolder(ctx.Event.GroupID, folderID) } -// GetGroupFileUrl 获取群文件资源链接 +// GetGroupFileURL 获取群文件资源链接 // https://github.com/Mrs4s/go-cqhttp/blob/master/docs/cqhttp.md#%E8%8E%B7%E5%8F%96%E7%BE%A4%E6%96%87%E4%BB%B6%E8%B5%84%E6%BA%90%E9%93%BE%E6%8E%A5 -func (ctx *Ctx) GetGroupFileUrl(groupID, busid int64, fileID string) string { +func (ctx *Ctx) GetGroupFileURL(groupID, busid int64, fileID string) string { return ctx.CallAction("get_group_file_url", Params{ "group_id": groupID, "file_id": fileID, @@ -692,10 +692,10 @@ func (ctx *Ctx) GetGroupFileUrl(groupID, busid int64, fileID string) string { }).Data.Get("url").Str } -// GetThisGroupFileUrl 获取本群文件资源链接 +// GetThisGroupFileURL 获取本群文件资源链接 // https://github.com/Mrs4s/go-cqhttp/blob/master/docs/cqhttp.md#%E8%8E%B7%E5%8F%96%E7%BE%A4%E6%96%87%E4%BB%B6%E8%B5%84%E6%BA%90%E9%93%BE%E6%8E%A5 -func (ctx *Ctx) GetThisGroupFileUrl(busid int64, fileID string) string { - return ctx.GetGroupFileUrl(ctx.Event.GroupID, busid, fileID) +func (ctx *Ctx) GetThisGroupFileURL(busid int64, fileID string) string { + return ctx.GetGroupFileURL(ctx.Event.GroupID, busid, fileID) } // UploadGroupFile 上传群文件 diff --git a/bot.go b/bot.go index 3af68b3..d3168ae 100644 --- a/bot.go +++ b/bot.go @@ -33,9 +33,9 @@ type Config struct { // APICallers 所有的APICaller列表, 通过self-ID映射 var APICallers callerMap -// APICaller is the interface of CallApi +// APICaller is the interface of CallAPI type APICaller interface { - CallApi(request APIRequest) (APIResponse, error) + CallAPI(request APIRequest) (APIResponse, error) } // Driver 与OneBot通信的驱动,使用driver.DefaultWebSocketDriver @@ -125,18 +125,18 @@ func RunAndBlock(op *Config, preblock func()) { } var ( - triggeredMessages = ttl.NewCache[int64, []message.MessageID](time.Minute * 5) + triggeredMessages = ttl.NewCache[int64, []message.ID](time.Minute * 5) triggeredMessagesMu = sync.Mutex{} ) type messageLogger struct { - msgid message.MessageID + msgid message.ID caller APICaller } -// CallApi 记录被触发的回复消息 -func (m *messageLogger) CallApi(request APIRequest) (rsp APIResponse, err error) { - rsp, err = m.caller.CallApi(request) +// CallAPI 记录被触发的回复消息 +func (m *messageLogger) CallAPI(request APIRequest) (rsp APIResponse, err error) { + rsp, err = m.caller.CallAPI(request) if err != nil { return } @@ -156,7 +156,7 @@ func (m *messageLogger) CallApi(request APIRequest) (rsp APIResponse, err error) } // GetTriggeredMessages 获取被 id 消息触发的回复消息 id -func GetTriggeredMessages(id message.MessageID) []message.MessageID { +func GetTriggeredMessages(id message.ID) []message.ID { triggeredMessagesMu.Lock() defer triggeredMessagesMu.Unlock() return triggeredMessages.Get(id.ID()) @@ -167,7 +167,7 @@ func processEventAsync(response []byte, caller APICaller, maxwait time.Duration) var event Event _ = json.Unmarshal(response, &event) event.RawEvent = gjson.Parse(helper.BytesToString(response)) - var msgid message.MessageID + var msgid message.ID messageID, err := strconv.ParseInt(helper.BytesToString(event.RawMessageID), 10, 64) if err == nil { event.MessageID = messageID @@ -397,7 +397,7 @@ func preprocessMessageEvent(e *Event) { msgs := message.ParseMessage(e.NativeMessage) if len(msgs) > 0 { - filtered := make([]message.MessageSegment, 0, len(msgs)) + filtered := make([]message.Segment, 0, len(msgs)) // trim space after at and remove empty text segment for i := range msgs { if i < len(msgs)-1 && msgs[i].Type == "at" && msgs[i+1].Type == "text" { @@ -486,12 +486,12 @@ func RangeBot(iter func(id int64, ctx *Ctx) bool) { // GetFirstSuperUser 在 qqs 中获得 SuperUsers 列表的首个 qq // // 找不到返回 -1 -func (c *Config) GetFirstSuperUser(qqs ...int64) int64 { +func (op *Config) GetFirstSuperUser(qqs ...int64) int64 { m := make(map[int64]struct{}, len(qqs)*4) for _, qq := range qqs { m[qq] = struct{}{} } - for _, qq := range c.SuperUsers { + for _, qq := range op.SuperUsers { if _, ok := m[qq]; ok { return qq } diff --git a/context.go b/context.go index 11c661d..76a433b 100644 --- a/context.go +++ b/context.go @@ -86,7 +86,7 @@ func (ctx *Ctx) CheckSession() Rule { } // Send 快捷发送消息/合并转发 -func (ctx *Ctx) Send(msg interface{}) message.MessageID { +func (ctx *Ctx) Send(msg interface{}) message.ID { event := ctx.Event m, ok := msg.(message.Message) if !ok { @@ -112,7 +112,7 @@ func (ctx *Ctx) Send(msg interface{}) message.MessageID { } // SendChain 快捷发送消息/合并转发-消息链 -func (ctx *Ctx) SendChain(msg ...message.MessageSegment) message.MessageID { +func (ctx *Ctx) SendChain(msg ...message.Segment) message.ID { return ctx.Send((message.Message)(msg)) } @@ -126,8 +126,8 @@ func (ctx *Ctx) Echo(response []byte) { } // FutureEvent ... -func (ctx *Ctx) FutureEvent(Type string, rule ...Rule) *FutureEvent { - return ctx.ma.FutureEvent(Type, rule...) +func (ctx *Ctx) FutureEvent(typ string, rule ...Rule) *FutureEvent { + return ctx.ma.FutureEvent(typ, rule...) } // Get .. diff --git a/docs/content/start/install.md b/docs/content/start/install.md index 645ffff..af7ba2d 100644 --- a/docs/content/start/install.md +++ b/docs/content/start/install.md @@ -12,7 +12,7 @@ bookComments: true ### 安装Go -首先需要安装Go(支持版本1.18+), 你可以在 +首先需要安装Go(支持版本1.20+), 你可以在 {{< button href="https://golang.org/dl" >}} Go官网{{< /button >}} 或者{{< button href="https://golang.google.cn/dl">}}Go中国镜像站{{< /button >}} (国内用户推荐)找到对应的安装包 diff --git a/driver/wsclient.go b/driver/wsclient.go index d4f15d7..dc7af13 100644 --- a/driver/wsclient.go +++ b/driver/wsclient.go @@ -29,7 +29,7 @@ type WSClient struct { conn *websocket.Conn mu sync.Mutex // 写锁 seqMap seqSyncMap - Url string // ws连接地址 + URL string // ws连接地址 AccessToken string selfID int64 } @@ -37,14 +37,14 @@ type WSClient struct { // NewWebSocketClient 默认Driver,使用正向WS通信 func NewWebSocketClient(url, accessToken string) *WSClient { return &WSClient{ - Url: url, + URL: url, AccessToken: accessToken, } } // Connect 连接ws服务端 func (ws *WSClient) Connect() { - log.Infof("[ws] 开始尝试连接到Websocket服务器: %v", ws.Url) + log.Infof("[ws] 开始尝试连接到Websocket服务器: %v", ws.URL) header := http.Header{ "X-Client-Role": []string{"Universal"}, "User-Agent": []string{"ZeroBot/1.6.3"}, @@ -53,7 +53,7 @@ func (ws *WSClient) Connect() { header["Authorization"] = []string{"Bearer " + ws.AccessToken} } - network, address := resolveURI(ws.Url) + network, address := resolveURI(ws.URL) dialer := websocket.Dialer{ NetDial: func(_, addr string) (net.Conn, error) { if network == "unix" { @@ -73,7 +73,7 @@ func (ws *WSClient) Connect() { for { conn, res, err := dialer.Dial(address, header) if err != nil { - log.Warnf("[ws] 连接到Websocket服务器 %v 时出现错误: %v", ws.Url, err) + log.Warnf("[ws] 连接到Websocket服务器 %v 时出现错误: %v", ws.URL, err) time.Sleep(2 * time.Second) // 等待两秒后重新连接 continue } @@ -84,13 +84,13 @@ func (ws *WSClient) Connect() { } err = ws.conn.ReadJSON(&rsp) if err != nil { - log.Warnf("[ws] 与Websocket服务器 %v 握手时出现错误: %v", ws.Url, err) + log.Warnf("[ws] 与Websocket服务器 %v 握手时出现错误: %v", ws.URL, err) time.Sleep(2 * time.Second) // 等待两秒后重新连接 continue } ws.selfID = rsp.SelfID zero.APICallers.Store(ws.selfID, ws) // 添加Caller到 APICaller list... - log.Infof("[ws] 连接Websocket服务器: %s 成功, 账号: %d", ws.Url, rsp.SelfID) + log.Infof("[ws] 连接Websocket服务器: %s 成功, 账号: %d", ws.URL, rsp.SelfID) break } } @@ -137,8 +137,8 @@ func (ws *WSClient) nextSeq() uint64 { return atomic.AddUint64(&ws.seq, 1) } -// CallApi 发送ws请求 -func (ws *WSClient) CallApi(req zero.APIRequest) (zero.APIResponse, error) { +// CallAPI 发送ws请求 +func (ws *WSClient) CallAPI(req zero.APIRequest) (zero.APIResponse, error) { ch := make(chan zero.APIResponse, 1) req.Echo = ws.nextSeq() ws.seqMap.Store(req.Echo, ch) diff --git a/driver/wsserver.go b/driver/wsserver.go index 9ed46b5..287d76b 100644 --- a/driver/wsserver.go +++ b/driver/wsserver.go @@ -23,7 +23,7 @@ import ( // WSServer ... type WSServer struct { - Url string // ws连接地址 + URL string // ws连接地址 AccessToken string lstn net.Listener caller chan *WSSCaller @@ -34,7 +34,7 @@ type WSServer struct { // UnmarshalJSON init WSServer with waitn=16 func (wss *WSServer) UnmarshalJSON(data []byte) error { type jsoncfg struct { - Url string // ws连接地址 + URL string // ws连接地址 AccessToken string } err := json.Unmarshal(data, (*jsoncfg)(unsafe.Pointer(wss))) @@ -48,7 +48,7 @@ func (wss *WSServer) UnmarshalJSON(data []byte) error { // NewWebSocketServer 使用反向WS通信 func NewWebSocketServer(waitn int, url, accessToken string) *WSServer { return &WSServer{ - Url: url, + URL: url, AccessToken: accessToken, caller: make(chan *WSSCaller, waitn), } @@ -64,14 +64,14 @@ type WSSCaller struct { } var upgrader = websocket.Upgrader{ - CheckOrigin: func(r *http.Request) bool { + CheckOrigin: func(_ *http.Request) bool { return true }, } // Connect 监听ws服务 func (wss *WSServer) Connect() { - network, address := resolveURI(wss.Url) + network, address := resolveURI(wss.URL) uri, err := url.Parse(address) if err == nil && uri.Scheme != "" { address = uri.Host @@ -132,7 +132,7 @@ func (wss *WSServer) any(w http.ResponseWriter, r *http.Request) { } err = conn.ReadJSON(&rsp) if err != nil { - log.Warnf("[wss] 与Websocket服务器 %v 握手时出现错误: %v", wss.Url, err) + log.Warnf("[wss] 与Websocket服务器 %v 握手时出现错误: %v", wss.URL, err) return } @@ -141,7 +141,7 @@ func (wss *WSServer) any(w http.ResponseWriter, r *http.Request) { selfID: rsp.SelfID, } zero.APICallers.Store(rsp.SelfID, c) // 添加Caller到 APICaller list... - log.Infof("[wss] 连接Websocket服务器: %s 成功, 账号: %d", wss.Url, rsp.SelfID) + log.Infof("[wss] 连接Websocket服务器: %s 成功, 账号: %d", wss.URL, rsp.SelfID) wss.caller <- c } @@ -208,8 +208,8 @@ func (wssc *WSSCaller) nextSeq() uint64 { return atomic.AddUint64(&wssc.seq, 1) } -// CallApi 发送ws请求 -func (wssc *WSSCaller) CallApi(req zero.APIRequest) (zero.APIResponse, error) { +// CallAPI 发送ws请求 +func (wssc *WSSCaller) CallAPI(req zero.APIRequest) (zero.APIResponse, error) { ch := make(chan zero.APIResponse, 1) req.Echo = wssc.nextSeq() wssc.seqMap.Store(req.Echo, ch) diff --git a/event_channel.go b/event_channel.go index 890315e..004ca53 100644 --- a/event_channel.go +++ b/event_channel.go @@ -9,19 +9,19 @@ type FutureEvent struct { } // NewFutureEvent 创建一个FutureEvent, 并返回其指针 -func NewFutureEvent(Type string, Priority int, Block bool, rule ...Rule) *FutureEvent { +func NewFutureEvent(typ string, priority int, block bool, rule ...Rule) *FutureEvent { return &FutureEvent{ - Type: Type, - Priority: Priority, + Type: typ, + Priority: priority, Rule: rule, - Block: Block, + Block: block, } } // FutureEvent 返回一个 FutureEvent 实例指针,用于获取满足 Rule 的 未来事件 -func (m *Matcher) FutureEvent(Type string, rule ...Rule) *FutureEvent { +func (m *Matcher) FutureEvent(typ string, rule ...Rule) *FutureEvent { return &FutureEvent{ - Type: Type, + Type: typ, Priority: m.Priority, Block: m.Block, Rule: rule, diff --git a/example/manager/rule.go b/example/manager/rule.go index e7bb1f1..f3e36c8 100644 --- a/example/manager/rule.go +++ b/example/manager/rule.go @@ -175,7 +175,7 @@ func init() { Handle(func(ctx *zero.Ctx) { msg := `---服务列表---` i := 0 - ForEach(func(key string, manager *Manager) bool { + ForEach(func(key string, _ *Manager) bool { i++ msg += "\n" + strconv.Itoa(i) + `: ` + key return true diff --git a/example/music/main.go b/example/music/main.go index 68ee28c..75aed67 100644 --- a/example/music/main.go +++ b/example/music/main.go @@ -53,7 +53,7 @@ func init() { ctx.Send("歌曲名不合法oxo") } } - zero.RangeBot(func(id int64, ctx2 *zero.Ctx) bool { // test the range bot function + zero.RangeBot(func(_ int64, ctx2 *zero.Ctx) bool { // test the range bot function ctx2.SendGroupMessage(ctx.Event.GroupID, message.Music("163", queryNeteaseMusic(cmd.Args))) return true }) diff --git a/example/shell/shell.go b/example/shell/shell.go index 72de57a..b5a6704 100644 --- a/example/shell/shell.go +++ b/example/shell/shell.go @@ -1,7 +1,7 @@ package shell import ( - "fmt" + "github.com/sirupsen/logrus" zero "github.com/wdvxdr1123/ZeroBot" ) @@ -20,11 +20,11 @@ type Ping struct { func init() { zero.OnShell("ping", Ping{}).Handle(func(ctx *zero.Ctx) { ping := ctx.State["flag"].(*Ping) // Note: 指针类型 - fmt.Println("ping host:", ping.Host) - fmt.Println("ping timeout:", ping.Timeout) - fmt.Println("ping t:", ping.T) + logrus.Infoln("ping host:", ping.Host) + logrus.Infoln("ping timeout:", ping.Timeout) + logrus.Infoln("ping t:", ping.T) for i, v := range ctx.State["args"].([]string) { - fmt.Println("args", i, ":", v) + logrus.Infoln("args", i, ":", v) } }) } diff --git a/extension/filter/filter.go b/extension/filter/filter.go index 658eb91..39ab744 100644 --- a/extension/filter/filter.go +++ b/extension/filter/filter.go @@ -9,21 +9,21 @@ import ( ) type ( - FilterFunc func(gjson.Result) bool - field struct { + Func func(gjson.Result) bool + Field struct { key string } ) -// Filter return a rule filter the message. -func Filter[Ctx any](getevent func(Ctx) gjson.Result, filters ...FilterFunc) func(ctx Ctx) bool { +// New return a rule filter the message. +func New[Ctx any](getevent func(Ctx) gjson.Result, filters ...Func) func(ctx Ctx) bool { return func(ctx Ctx) bool { return And(filters...)(getevent(ctx)) } } // Or ... -func Or(filters ...FilterFunc) FilterFunc { +func Or(filters ...Func) Func { return func(result gjson.Result) bool { for _, filter := range filters { if filter(result) { @@ -35,7 +35,7 @@ func Or(filters ...FilterFunc) FilterFunc { } // And ... -func And(filters ...FilterFunc) FilterFunc { +func And(filters ...Func) Func { return func(result gjson.Result) bool { for _, filter := range filters { if !filter(result) { @@ -47,47 +47,47 @@ func And(filters ...FilterFunc) FilterFunc { } // Not ... -func Not(filter FilterFunc) FilterFunc { +func Not(filter Func) Func { return func(result gjson.Result) bool { return !filter(result) } } -// Field ... -func Field(str string) *field { - return &field{key: str} +// NewField ... +func NewField(str string) *Field { + return &Field{key: str} } // Any ... -func (f *field) Any(filter ...FilterFunc) FilterFunc { +func (f *Field) Any(filter ...Func) Func { return func(result gjson.Result) bool { return Or(filter...)(result.Get(f.key)) } } // All ... -func (f *field) All(filter ...FilterFunc) FilterFunc { +func (f *Field) All(filter ...Func) Func { return func(result gjson.Result) bool { return And(filter...)(result.Get(f.key)) } } // Equal ... -func Equal(str string) FilterFunc { +func Equal(str string) Func { return func(result gjson.Result) bool { return str == result.String() } } // NotEqual ... -func NotEqual(str string) FilterFunc { +func NotEqual(str string) Func { return func(result gjson.Result) bool { return str != result.String() } } // In ... -func In(i ...interface{}) FilterFunc { +func In(i ...interface{}) Func { ss := make([]string, 0) for _, v := range i { ss = append(ss, fmt.Sprint(v)) @@ -103,14 +103,14 @@ func In(i ...interface{}) FilterFunc { } // Contain ... -func Contain(str string) FilterFunc { +func Contain(str string) Func { return func(result gjson.Result) bool { return strings.Contains(result.String(), str) } } // Regex ... -func Regex(str string) FilterFunc { +func Regex(str string) Func { pat := regexp.MustCompile(str) return func(result gjson.Result) bool { return pat.MatchString(result.String()) diff --git a/extension/filter/filter_test.go b/extension/filter/filter_test.go index aa54dc0..cc61732 100644 --- a/extension/filter/filter_test.go +++ b/extension/filter/filter_test.go @@ -19,17 +19,17 @@ func TestFilter(t *testing.T) { event := &zero.Event{ RawEvent: rawEvent, } - result := Filter( + result := New( func(ctx *zero.Ctx) gjson.Result { return ctx.Event.RawEvent }, - Field("post_type").Any( + NewField("post_type").Any( Equal("notice"), Not( In("message"), ), ), - Field("user_id").All( + NewField("user_id").All( NotEqual("abs"), ), )(&zero.Ctx{Event: event}) diff --git a/message/cqcode.go b/message/cqcode.go index 39b600b..5ff6ce9 100644 --- a/message/cqcode.go +++ b/message/cqcode.go @@ -18,9 +18,8 @@ func ParseMessage(msg []byte) Message { x := gjson.Parse(helper.BytesToString(msg)) if x.IsArray() { return ParseMessageFromArray(x) - } else { - return ParseMessageFromString(x.String()) } + return ParseMessageFromString(x.String()) } // ParseMessageFromArray parses msg as type array to a Message. @@ -38,7 +37,7 @@ func ParseMessageFromArray(msgs gjson.Result) Message { return m } msgs.ForEach(func(_, item gjson.Result) bool { - message = append(message, MessageSegment{ + message = append(message, Segment{ Type: item.Get("type").String(), Data: parse2map(item.Get("data")), }) diff --git a/message/cqstring.go b/message/cqstring.go index 5fefa1e..5a773cf 100644 --- a/message/cqstring.go +++ b/message/cqstring.go @@ -6,7 +6,7 @@ package message // // CQ字符串转为消息 func ParseMessageFromString(raw string) (m Message) { - var seg MessageSegment + var seg Segment var k string m = Message{} for raw != "" { diff --git a/message/cqstring_test.go b/message/cqstring_test.go index ac77929..c3b0576 100644 --- a/message/cqstring_test.go +++ b/message/cqstring_test.go @@ -16,7 +16,7 @@ func TestParseMessageFromString(t *testing.T) { {`123213312312312312[]`, Message{Text("123213312312312312[]")}}, { `Gorilla[] [CQ:text]`, - Message{Text("Gorilla[] "), MessageSegment{Type: "text", Data: map[string]string{}}}, + Message{Text("Gorilla[] "), Segment{Type: "text", Data: map[string]string{}}}, }, { `[CQ:face,id=123][CQ:face,id=1234] `, @@ -26,8 +26,8 @@ func TestParseMessageFromString(t *testing.T) { `ȐĉņþƦȻƝƃ[CQ:rcnb][CQ:ɌćƞßɌĆnƅŕĉ,a=b]`, Message{ Text("ȐĉņþƦȻƝƃ"), - MessageSegment{Type: "rcnb", Data: map[string]string{}}, - MessageSegment{Type: "ɌćƞßɌĆnƅŕĉ", Data: map[string]string{"a": "b"}}, + Segment{Type: "rcnb", Data: map[string]string{}}, + Segment{Type: "ɌćƞßɌĆnƅŕĉ", Data: map[string]string{"a": "b"}}, }, }, { @@ -36,11 +36,11 @@ func TestParseMessageFromString(t *testing.T) { }, { `[CQ:face,id=123,id=123,id=123,id=123][CQ:face,id=1234][] [CQ:]`, - Message{Face(123), Face(1234), Text("[] "), MessageSegment{Type: "", Data: map[string]string{}}}, + Message{Face(123), Face(1234), Text("[] "), Segment{Type: "", Data: map[string]string{}}}, }, { `[CQ:image,file=file:///C:\path\to\my\img-123\###.png]`, // https://github.com/Mrs4s/go-cqhttp/issues/169 - Message{MessageSegment{Type: "image", Data: map[string]string{"file": "file:///C:\\path\\to\\my\\img-123\\###.png"}}}, + Message{Segment{Type: "image", Data: map[string]string{"file": "file:///C:\\path\\to\\my\\img-123\\###.png"}}}, }, } for i, test := range tests { diff --git a/message/message.go b/message/message.go index 4a52cd6..abf936e 100644 --- a/message/message.go +++ b/message/message.go @@ -16,12 +16,12 @@ import ( // Message impl the array form of message // https://github.com/botuniverse/onebot-11/tree/master/message/array.md#%E6%95%B0%E7%BB%84%E6%A0%BC%E5%BC%8F -type Message []MessageSegment +type Message []Segment -// MessageSegment impl the single message -// MessageSegment 消息数组 +// Segment impl the single message +// Segment 消息数组 // https://github.com/botuniverse/onebot-11/tree/master/message/array.md#%E6%95%B0%E7%BB%84%E6%A0%BC%E5%BC%8F -type MessageSegment struct { +type Segment struct { Type string `json:"type"` Data map[string]string `json:"data"` } @@ -80,7 +80,7 @@ func UnescapeCQCodeText(str string) string { // 与 String 不同之处在于,对于 // base64 的图片消息会将其哈希 // 方便 log 打印,不可用作发送 -func (m MessageSegment) CQCode() string { +func (m Segment) CQCode() string { sb := strings.Builder{} sb.WriteString("[CQ:") sb.WriteString(m.Type) @@ -115,7 +115,7 @@ func (m MessageSegment) CQCode() string { } // String impls the interface fmt.Stringer -func (m MessageSegment) String() string { +func (m Segment) String() string { sb := strings.Builder{} sb.WriteString("[CQ:") sb.WriteString(m.Type) @@ -165,8 +165,8 @@ func (m Message) String() string { // Text 纯文本 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E7%BA%AF%E6%96%87%E6%9C%AC -func Text(text ...interface{}) MessageSegment { - return MessageSegment{ +func Text(text ...interface{}) Segment { + return Segment{ Type: "text", Data: map[string]string{ "text": fmt.Sprint(text...), @@ -176,8 +176,8 @@ func Text(text ...interface{}) MessageSegment { // Face QQ表情 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#qq-%E8%A1%A8%E6%83%85 -func Face(id int) MessageSegment { - return MessageSegment{ +func Face(id int) Segment { + return Segment{ Type: "face", Data: map[string]string{ "id": strconv.Itoa(id), @@ -187,8 +187,8 @@ func Face(id int) MessageSegment { // File 文件 // https://llonebot.github.io/zh-CN/develop/extends_api -func File(file, name string) MessageSegment { - return MessageSegment{ +func File(file, name string) Segment { + return Segment{ Type: "file", Data: map[string]string{ "file": file, @@ -204,8 +204,8 @@ func File(file, name string) MessageSegment { // https://llonebot.github.io/zh-CN/develop/extends_api // // summary: LLOneBot的扩展字段:图片预览文字 -func Image(file string, summary ...interface{}) MessageSegment { - m := MessageSegment{ +func Image(file string, summary ...interface{}) Segment { + m := Segment{ Type: "image", Data: map[string]string{ "file": file, @@ -219,8 +219,8 @@ func Image(file string, summary ...interface{}) MessageSegment { // ImageBytes 普通图片 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E5%9B%BE%E7%89%87 -func ImageBytes(data []byte) MessageSegment { - return MessageSegment{ +func ImageBytes(data []byte) Segment { + return Segment{ Type: "image", Data: map[string]string{ "file": "base64://" + base64.StdEncoding.EncodeToString(data), @@ -230,8 +230,8 @@ func ImageBytes(data []byte) MessageSegment { // Record 语音 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E8%AF%AD%E9%9F%B3 -func Record(file string) MessageSegment { - return MessageSegment{ +func Record(file string) Segment { + return Segment{ Type: "record", Data: map[string]string{ "file": file, @@ -241,8 +241,8 @@ func Record(file string) MessageSegment { // Video 短视频 // https://github.com/botuniverse/onebot-11/blob/master/message/segment.md#%E7%9F%AD%E8%A7%86%E9%A2%91 -func Video(file string) MessageSegment { - return MessageSegment{ +func Video(file string) Segment { + return Segment{ Type: "video", Data: map[string]string{ "file": file, @@ -252,11 +252,11 @@ func Video(file string) MessageSegment { // At @某人 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E6%9F%90%E4%BA%BA -func At(qq int64) MessageSegment { +func At(qq int64) Segment { if qq == 0 { return AtAll() } - return MessageSegment{ + return Segment{ Type: "at", Data: map[string]string{ "qq": strconv.FormatInt(qq, 10), @@ -266,8 +266,8 @@ func At(qq int64) MessageSegment { // AtAll @全体成员 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E6%9F%90%E4%BA%BA -func AtAll() MessageSegment { - return MessageSegment{ +func AtAll() Segment { + return Segment{ Type: "at", Data: map[string]string{ "qq": "all", @@ -277,8 +277,8 @@ func AtAll() MessageSegment { // Music 音乐分享 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E9%9F%B3%E4%B9%90%E5%88%86%E4%BA%AB- -func Music(mType string, id int64) MessageSegment { - return MessageSegment{ +func Music(mType string, id int64) Segment { + return Segment{ Type: "music", Data: map[string]string{ "type": mType, @@ -289,8 +289,8 @@ func Music(mType string, id int64) MessageSegment { // CustomMusic 音乐自定义分享 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E9%9F%B3%E4%B9%90%E8%87%AA%E5%AE%9A%E4%B9%89%E5%88%86%E4%BA%AB- -func CustomMusic(url, audio, title string) MessageSegment { - return MessageSegment{ +func CustomMusic(url, audio, title string) Segment { + return Segment{ Type: "music", Data: map[string]string{ "type": "custom", @@ -301,14 +301,14 @@ func CustomMusic(url, audio, title string) MessageSegment { } } -// MessageID 对于 qq 消息, i 与 s 相同 +// ID 对于 qq 消息, i 与 s 相同 // 对于 guild 消息, i 为 s 的 ISO crc64 -type MessageID struct { +type ID struct { i int64 s string } -func NewMessageIDFromString(raw string) (m MessageID) { +func NewMessageIDFromString(raw string) (m ID) { var err error m.i, err = strconv.ParseInt(raw, 10, 64) if err != nil { @@ -320,13 +320,13 @@ func NewMessageIDFromString(raw string) (m MessageID) { return } -func NewMessageIDFromInteger(raw int64) (m MessageID) { +func NewMessageIDFromInteger(raw int64) (m ID) { m.s = strconv.FormatInt(raw, 10) m.i = raw return } -func (m MessageID) MarshalJSON() ([]byte, error) { +func (m ID) MarshalJSON() ([]byte, error) { sb := bytes.NewBuffer(make([]byte, 0, len(m.s)+2)) _, err := strconv.ParseInt(m.s, 10, 64) if err != nil { @@ -339,17 +339,17 @@ func (m MessageID) MarshalJSON() ([]byte, error) { return sb.Bytes(), nil } -func (m MessageID) String() string { +func (m ID) String() string { return m.s } -func (m MessageID) ID() int64 { +func (m ID) ID() int64 { return m.i } // Reply 回复 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E5%9B%9E%E5%A4%8D -func Reply(id interface{}) MessageSegment { +func Reply(id interface{}) Segment { s := "" switch i := id.(type) { case int64: @@ -363,7 +363,7 @@ func Reply(id interface{}) MessageSegment { case fmt.Stringer: s = i.String() } - return MessageSegment{ + return Segment{ Type: "reply", Data: map[string]string{ "id": s, @@ -373,8 +373,8 @@ func Reply(id interface{}) MessageSegment { // Forward 合并转发 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E5%90%88%E5%B9%B6%E8%BD%AC%E5%8F%91- -func Forward(id string) MessageSegment { - return MessageSegment{ +func Forward(id string) Segment { + return Segment{ Type: "forward", Data: map[string]string{ "id": id, @@ -384,8 +384,8 @@ func Forward(id string) MessageSegment { // Node 合并转发节点 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E5%90%88%E5%B9%B6%E8%BD%AC%E5%8F%91%E8%8A%82%E7%82%B9- -func Node(id int64) MessageSegment { - return MessageSegment{ +func Node(id int64) Segment { + return Segment{ Type: "node", Data: map[string]string{ "id": strconv.FormatInt(id, 10), @@ -395,20 +395,20 @@ func Node(id int64) MessageSegment { // CustomNode 自定义合并转发节点 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#%E5%90%88%E5%B9%B6%E8%BD%AC%E5%8F%91%E8%87%AA%E5%AE%9A%E4%B9%89%E8%8A%82%E7%82%B9 -func CustomNode(nickname string, userID int64, content interface{}) MessageSegment { +func CustomNode(nickname string, userID int64, content interface{}) Segment { var str string switch c := content.(type) { case string: str = c case Message: str = c.String() - case []MessageSegment: + case []Segment: str = (Message)(c).String() default: b, _ := json.Marshal(content) str = helper.BytesToString(b) } - return MessageSegment{ + return Segment{ Type: "node", Data: map[string]string{ "uin": strconv.FormatInt(userID, 10), @@ -420,8 +420,8 @@ func CustomNode(nickname string, userID int64, content interface{}) MessageSegme // XML 消息 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#xml-%E6%B6%88%E6%81%AF -func XML(data string) MessageSegment { - return MessageSegment{ +func XML(data string) Segment { + return Segment{ Type: "xml", Data: map[string]string{ "data": data, @@ -431,8 +431,8 @@ func XML(data string) MessageSegment { // JSON 消息 // https://github.com/botuniverse/onebot-11/tree/master/message/segment.md#xml-%E6%B6%88%E6%81%AF -func JSON(data string) MessageSegment { - return MessageSegment{ +func JSON(data string) Segment { + return Segment{ Type: "json", Data: map[string]string{ "data": data, @@ -446,8 +446,8 @@ func JSON(data string) MessageSegment { // https://github.com/Mrs4s/go-cqhttp/blob/master/docs/cqhttp.md#%E7%A4%BC%E7%89%A9 // // Deprecated: 群礼物改版 -func Gift(userID string, giftID string) MessageSegment { - return MessageSegment{ +func Gift(userID string, giftID string) Segment { + return Segment{ Type: "gift", Data: map[string]string{ "qq": userID, @@ -458,8 +458,8 @@ func Gift(userID string, giftID string) MessageSegment { // Poke 戳一戳 // https://github.com/Mrs4s/go-cqhttp/blob/master/docs/cqhttp.md#%E6%88%B3%E4%B8%80%E6%88%B3 -func Poke(userID int64) MessageSegment { - return MessageSegment{ +func Poke(userID int64) Segment { + return Segment{ Type: "poke", Data: map[string]string{ "qq": strconv.FormatInt(userID, 10), @@ -469,8 +469,8 @@ func Poke(userID int64) MessageSegment { // TTS 文本转语音 // https://github.com/Mrs4s/go-cqhttp/blob/master/docs/cqhttp.md#%E6%96%87%E6%9C%AC%E8%BD%AC%E8%AF%AD%E9%9F%B3 -func TTS(text string) MessageSegment { - return MessageSegment{ +func TTS(text string) Segment { + return Segment{ Type: "tts", Data: map[string]string{ "text": text, @@ -479,7 +479,7 @@ func TTS(text string) MessageSegment { } // Add 为 MessageSegment 的 Data 增加一个字段 -func (m MessageSegment) Add(key string, val interface{}) MessageSegment { +func (m Segment) Add(key string, val interface{}) Segment { switch val := val.(type) { case string: m.Data[key] = val @@ -496,7 +496,7 @@ func (m MessageSegment) Add(key string, val interface{}) MessageSegment { } // Chain 将两个 Data 合并 -func (m MessageSegment) Chain(data map[string]string) MessageSegment { +func (m Segment) Chain(data map[string]string) Segment { for k, v := range data { m.Data[k] = v } @@ -504,6 +504,6 @@ func (m MessageSegment) Chain(data map[string]string) MessageSegment { } // ReplyWithMessage returns a reply message -func ReplyWithMessage(messageID interface{}, m ...MessageSegment) Message { +func ReplyWithMessage(messageID interface{}, m ...Segment) Message { return append(Message{Reply(messageID)}, m...) } diff --git a/message/message_test.go b/message/message_test.go index 7883d59..f04424e 100644 --- a/message/message_test.go +++ b/message/message_test.go @@ -9,7 +9,7 @@ import ( func TestMessageID(t *testing.T) { id := NewMessageIDFromString("test case") - msg := Message([]MessageSegment{Reply(id)}) + msg := Message([]Segment{Reply(id)}) data, err := json.Marshal(&msg) if err != nil { t.Fatal(err) diff --git a/ring_test.go b/ring_test.go index 9776c49..3f48bfb 100644 --- a/ring_test.go +++ b/ring_test.go @@ -1,7 +1,6 @@ package zero import ( - "fmt" "math/rand" "testing" "time" @@ -44,5 +43,5 @@ func TestRing(t *testing.T) { func testProcess(response []byte, _ APICaller, _ time.Duration) { time.Sleep(time.Duration(rand.Intn(100)+1) * time.Microsecond) buf[response[0]] = response[1] - fmt.Println(response[0], "processed") + // fmt.Println(response[0], "processed") } diff --git a/rules.go b/rules.go index 0490d8d..67d42af 100644 --- a/rules.go +++ b/rules.go @@ -12,8 +12,8 @@ import ( ) // Type check the ctx.Event's type -func Type(type_ string) Rule { - t := strings.SplitN(type_, "/", 3) +func Type(typ string) Rule { + t := strings.SplitN(typ, "/", 3) return func(ctx *Ctx) bool { if len(t) > 0 && t[0] != ctx.Event.PostType { return false @@ -174,9 +174,9 @@ func OnlyToMe(ctx *Ctx) bool { } // CheckUser only triggered by specific person -func CheckUser(userId ...int64) Rule { +func CheckUser(userID ...int64) Rule { return func(ctx *Ctx) bool { - for _, uid := range userId { + for _, uid := range userID { if ctx.Event.UserID == uid { return true } @@ -186,9 +186,9 @@ func CheckUser(userId ...int64) Rule { } // CheckGroup only triggered in specific group -func CheckGroup(grpId ...int64) Rule { +func CheckGroup(grpID ...int64) Rule { return func(ctx *Ctx) bool { - for _, gid := range grpId { + for _, gid := range grpID { if ctx.Event.GroupID == gid { return true } diff --git a/types.go b/types.go index b5ef3bc..6d91e51 100644 --- a/types.go +++ b/types.go @@ -92,7 +92,7 @@ type Event struct { // Message 消息 type Message struct { Elements message.Message - MessageId message.MessageID + MessageID message.ID Sender *User MessageType string } diff --git a/utils/async/async.go b/utils/async/async.go index 6f3b4ee..6280702 100644 --- a/utils/async/async.go +++ b/utils/async/async.go @@ -13,46 +13,46 @@ import ( var DefaultWorkerNum = runtime.GOMAXPROCS(0) * 2 type ( - // IAsync interface - IAsync[Result any] interface { - AddTask(task Task[Result]) - Result() <-chan AsyncResult[Result] + // Executor interface + Executor[R any] interface { + AddTask(task Task[R]) + Result() <-chan Result[R] } - // AsyncResult result struct - AsyncResult[Result any] struct { - Value Result + // Result ... + Result[R any] struct { + Value R Err error } - async[Result any] struct { - tasks []Task[Result] + async[R any] struct { + tasks []Task[R] wg sync.WaitGroup maxWorkerNum int } // Task task func - Task[Result any] func() (Result, error) + Task[R any] func() (R, error) ) -// NewAsync ... -func NewAsync[Result any](maxWorkerNum int) IAsync[Result] { +// NewExec ... +func NewExec[R any](maxWorkerNum int) Executor[R] { if maxWorkerNum <= 0 { maxWorkerNum = DefaultWorkerNum } - return &async[Result]{ + return &async[R]{ maxWorkerNum: maxWorkerNum, wg: sync.WaitGroup{}, } } -func (a *async[Result]) AddTask(task Task[Result]) { +func (a *async[R]) AddTask(task Task[R]) { a.tasks = append(a.tasks, task) } -func (a *async[Result]) Result() <-chan AsyncResult[Result] { - taskChan := make(chan Task[Result]) - resultChan := make(chan AsyncResult[Result]) +func (a *async[R]) Result() <-chan Result[R] { + taskChan := make(chan Task[R]) + resultChan := make(chan Result[R]) taskNum := len(a.tasks) workerNum := int(math.Min(float64(taskNum), float64(a.maxWorkerNum))) a.wg.Add(taskNum) @@ -60,7 +60,7 @@ func (a *async[Result]) Result() <-chan AsyncResult[Result] { for i := 0; i < workerNum; i++ { go func() { for task := range taskChan { - result := AsyncResult[Result]{} + result := Result[R]{} result.Value, result.Err = task() resultChan <- result a.wg.Done() From c41869fa3b18d4b4234debc21213765cba4c63c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Sun, 13 Oct 2024 00:13:18 +0900 Subject: [PATCH 3/4] chore: make lint happy --- matcher_test.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/matcher_test.go b/matcher_test.go index 5c7e8a1..807e3ed 100644 --- a/matcher_test.go +++ b/matcher_test.go @@ -1,7 +1,7 @@ package zero import ( - "slices" + "cmp" "strconv" "testing" ) @@ -38,10 +38,26 @@ func Test_sortMatcher(t *testing.T) { for i := 0; i < block*batch; i += block { batchRes := result[i : i+block] // 优先级从1开始的matcher先注册后执行,所以结果是逆序的 - slices.Reverse(batchRes) - if !slices.IsSorted(batchRes) { + reverse(batchRes) + if !isSorted(batchRes) { t.Fatalf("matcherList is not sorted, sort func is not stable: %v", batchRes) } } +} + +// reverse reverses the elements of the slice in place. +func reverse[S ~[]E, E any](s S) { + for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } +} +// isSorted reports whether x is sorted in ascending order. +func isSorted[S ~[]E, E cmp.Ordered](x S) bool { + for i := len(x) - 1; i > 0; i-- { + if cmp.Less(x[i], x[i-1]) { + return false + } + } + return true } From 5d23e7cd536f4ea0950215f657a2426cf6a27026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Sun, 13 Oct 2024 00:16:07 +0900 Subject: [PATCH 4/4] chore: make lint happy --- matcher_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/matcher_test.go b/matcher_test.go index 807e3ed..2742cc3 100644 --- a/matcher_test.go +++ b/matcher_test.go @@ -1,7 +1,6 @@ package zero import ( - "cmp" "strconv" "testing" ) @@ -53,9 +52,9 @@ func reverse[S ~[]E, E any](s S) { } // isSorted reports whether x is sorted in ascending order. -func isSorted[S ~[]E, E cmp.Ordered](x S) bool { +func isSorted(x []int) bool { for i := len(x) - 1; i > 0; i-- { - if cmp.Less(x[i], x[i-1]) { + if x[i] < x[i-1] { return false } }