Skip to content

Commit

Permalink
feat: error code (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tohrusky authored Jul 15, 2024
1 parent 0191f13 commit f0f7de4
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 1 deletion.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ build: ## build binary file
gen: ## generate CURD code
${GO} run ./cmd/gen/main.go

.PHONY: gen_error_code
gen_error_code: ## generate error code
${GO} generate github.com/TensoRaws/NuxBT-Backend/module/error/gen

.PHONY: test
test: tidy ## go test
${GO} test ./...

.PHONY: lint
lint: ## go lint
lint: gen_error_code
golangci-lint run
pre-commit install # pip install pre-commit
pre-commit run --all-files
22 changes: 22 additions & 0 deletions module/error/code.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package error

type Code uint32

const (
// DO NOT EDIT
// gen code start
InternalError Code = 10000 + iota
UnknownError
InvalidParams
InvalidToken
InvalidUserName
// gen code end
// DO NOT EDIT
)

func (c Code) String() string {
if str, ok := codeToString[c]; ok {
return str
}
return "Unknown ErrorCode"
}
11 changes: 11 additions & 0 deletions module/error/code.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Code generated by go generate; DO NOT EDIT.
// Code generated by go generate; DO NOT EDIT.
// Code generated by go generate; DO NOT EDIT.

export const enum ErrorCode {
InternalError = 10000,
UnknownError,
InvalidParams,
InvalidToken,
InvalidUserName
}
13 changes: 13 additions & 0 deletions module/error/code_map.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

177 changes: 177 additions & 0 deletions module/error/gen/map.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
//go:generate go run map.go
package main

import (
"fmt"
"go/format"
"os"
"path/filepath"
"strconv"
"strings"
)

// buildConstBlock 从文件 content 中构建 const 块
func buildConstBlock(filename string) ([]string, uint32) {
var iotaBegin uint32 = 0

file, err := os.ReadFile(filename)
if err != nil {
_ = fmt.Errorf("read file error: %v", err)
os.Exit(1)
return nil, 0
}

content := string(file)

// 按 \n\t 分割内容
lines := strings.Split(content, "\n\t")

// 构建 const 块
constBlock := make([]string, 0)
buildBlockFlag := false
for _, line := range lines {
if strings.Contains(line, "gen code start") {
buildBlockFlag = true
continue
}
if strings.Contains(line, "gen code end") {
break
}
if buildBlockFlag {
if strings.Contains(line, "iota") { // OK Code = 10000 + iota
l := strings.Split(line, " ")
constBlock = append(constBlock, l[0])
// string to uint32
b, _ := strconv.Atoi(l[3])
iotaBegin = uint32(b)
} else {
constBlock = append(constBlock, line)
}
}
}

if iotaBegin == 0 {
fmt.Println("Error: iota not found")
os.Exit(1)
}

return constBlock, iotaBegin
}

// handleCapString 按字符串的的大写字母分割字符串,用空格连接,首字母大写
func handleCapString(str string) string {
var buffer strings.Builder
for i, c := range str {
if i > 0 && 'A' <= c && c <= 'Z' {
buffer.WriteByte(' ')
}
if i == 0 {
buffer.WriteRune(c)
} else {
if 'A' <= c && c <= 'Z' {
// 将大写字母转换为小写字母
buffer.WriteRune(c + 32)
} else {
buffer.WriteRune(c)
}
}
}
return buffer.String()
}

// generateMap 生成映射代码
func generateMap(constBlock []string) string {
var mapLines []string
mapLines = append(mapLines, "// Code generated by go generate; DO NOT EDIT.")
mapLines = append(mapLines, "// Code generated by go generate; DO NOT EDIT.")
mapLines = append(mapLines, "// Code generated by go generate; DO NOT EDIT.")
mapLines = append(mapLines, "package error")
mapLines = append(mapLines, "")
mapLines = append(mapLines, "// codeToString use a map to store the string representation of Code")
mapLines = append(mapLines, "var codeToString = map[Code]string{")
for _, l := range constBlock {
mapLines = append(mapLines, fmt.Sprintf("\t%s: \"%s\",", l, handleCapString(l)))
}
mapLines = append(mapLines, "}")

// 格式化生成的代码
var buffer strings.Builder
for _, line := range mapLines {
buffer.WriteString(line + "\n")
}

source, _ := format.Source([]byte(buffer.String()))

return string(source)
}

// generateTypeScriptEnum 生成 TypeScript 的枚举
func generateTypeScriptEnum(constBlock []string, itoaBegin uint32) string {
var tsLines []string
tsLines = append(tsLines, "// Code generated by go generate; DO NOT EDIT.")
tsLines = append(tsLines, "// Code generated by go generate; DO NOT EDIT.")
tsLines = append(tsLines, "// Code generated by go generate; DO NOT EDIT.")
tsLines = append(tsLines, "")
tsLines = append(tsLines, "export const enum ErrorCode {")
for i, l := range constBlock {
switch {
case i == 0:
tsLines = append(tsLines, fmt.Sprintf(" %s = %s,", l, strconv.Itoa(int(itoaBegin))))
case i == len(constBlock)-1:
tsLines = append(tsLines, fmt.Sprintf(" %s", l))
default:
tsLines = append(tsLines, fmt.Sprintf(" %s,", l))
}
}
tsLines = append(tsLines, "}")

// 格式化生成的代码
var buffer strings.Builder
for _, line := range tsLines {
buffer.WriteString(line + "\n")
}
return buffer.String()
}

func main() {
// 获取当前工作目录
currentDir, err := os.Getwd()
fmt.Println("currentDir: ", currentDir)
if err != nil {
fmt.Println("Error getting current directory: " + err.Error())
os.Exit(1)
}

// 根据相对路径找到文件
filePath := filepath.Join(currentDir, "module/error/code.go")
mapFilePath := filepath.Join(currentDir, "module/error/code_map.go")
tsFilePath := filepath.Join(currentDir, "module/error/code.ts")
if _, err := os.Stat(filePath); err != nil {
currentDir = filepath.Dir(currentDir)
filePath = filepath.Join(currentDir, "code.go")
mapFilePath = filepath.Join(currentDir, "code_map.go")
tsFilePath = filepath.Join(currentDir, "code.ts")
}

constBlock, iotaBegin := buildConstBlock(filePath)

// 生成映射代码
mapCode := generateMap(constBlock)

// 生成 TypeScript 的枚举
tsCode := generateTypeScriptEnum(constBlock, iotaBegin)

// 写入到 code_map.go 文件
err = os.WriteFile(mapFilePath, []byte(mapCode), 0644)
if err != nil {
fmt.Println("Error writing code_map.go: " + err.Error())
os.Exit(1)
}

// 写入到 code.ts 文件
err = os.WriteFile(tsFilePath, []byte(tsCode), 0644)
if err != nil {
fmt.Println("Error writing code.ts: " + err.Error())
os.Exit(1)
}
}

0 comments on commit f0f7de4

Please sign in to comment.