From d7658fd6478b77a7c4dfc50b1cea36134ad90b02 Mon Sep 17 00:00:00 2001 From: yangyile Date: Wed, 27 Nov 2024 15:15:55 +0700 Subject: [PATCH] =?UTF-8?q?=E5=87=86=E5=A4=87=E4=BF=AE=E8=A1=A5=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 73 ++++++ LICENSE | 2 +- Makefile | 10 + README.md | 285 ++++++++-------------- README.zh.md | 245 ++++++++++++++----- utils_check.go => check_func.go | 13 - utils_check_test.go => check_func_test.go | 6 - go.mod | 6 +- go.sum | 12 +- internal/demos/demo3/main.go | 133 +++------- nc.go | 95 -------- nc_test.go | 133 ---------- np.go | 95 -------- np_test.go | 178 -------------- nv.go | 50 ---- nv_test.go | 133 ---------- rese.go | 49 ++++ rese_test.go | 92 +++++++ 18 files changed, 558 insertions(+), 1052 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 Makefile rename utils_check.go => check_func.go (69%) rename utils_check_test.go => check_func_test.go (81%) delete mode 100644 nc.go delete mode 100644 nc_test.go delete mode 100644 np.go delete mode 100644 np_test.go delete mode 100644 nv.go delete mode 100644 nv_test.go create mode 100644 rese.go create mode 100644 rese_test.go diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..7af6886 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,73 @@ +name: create-release + +on: + push: + branches: + - main # 监听 main 分支的 push 操作(编译和测试/代码检查) + tags: + - 'v*' # 监听以 'v' 开头的标签的 push 操作(发布 Release) + +jobs: + lint: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.23.x" + - uses: actions/checkout@v4 + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: latest + + test: + runs-on: ubuntu-latest + strategy: + matrix: + go: [ "1.22.x", "1.23.x" ] + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: ${{ matrix.go }} + + - name: Run test + run: make test COVERAGE_DIR=/tmp/coverage + + - name: Send goveralls coverage + uses: shogo82148/actions-goveralls@v1 + with: + path-to-profile: /tmp/coverage/combined.txt + flag-name: Go-${{ matrix.go }} + parallel: true + + check-coverage: + name: Check coverage + needs: [ test ] + runs-on: ubuntu-latest + steps: + - uses: shogo82148/actions-goveralls@v1 + with: + parallel-finished: true + + # 发布 Release + release: + name: Release a new version + needs: [ lint, test ] + runs-on: ubuntu-latest + # 仅在推送标签时执行 + if: ${{ success() && startsWith(github.ref, 'refs/tags/v') }} + steps: + # 1. 检出代码 + - name: Checkout code + uses: actions/checkout@v4 + + # 2. 创建 Release 和上传源码包 + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/LICENSE b/LICENSE index 6905e32..7b2c0ba 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 YANG-YI-LE +Copyright (c) 2024 yangyile-yyle88 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8348434 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +COVERAGE_DIR ?= .coverage + +# cp from: https://github.com/yyle88/zaplog/blob/f18b4dab6fdf1679714caed34b158c95dc01acc5/Makefile#L4 +test: + @-rm -r $(COVERAGE_DIR) + @mkdir $(COVERAGE_DIR) + make test-with-flags TEST_FLAGS='-v -race -covermode atomic -coverprofile $$(COVERAGE_DIR)/combined.txt -bench=. -benchmem -timeout 20m' + +test-with-flags: + @go test $(TEST_FLAGS) ./... diff --git a/README.md b/README.md index 9673bb2..397619c 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,41 @@ -# Done - Error Handling Simplified in Go +[![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/yyle88/done/release.yml?branch=main&label=BUILD)](https://github.com/yyle88/done/actions/workflows/release.yml?query=branch%3Amain) +[![GoDoc](https://pkg.go.dev/badge/github.com/yyle88/done)](https://pkg.go.dev/github.com/yyle88/done) +[![Coverage Status](https://img.shields.io/coveralls/github/yyle88/done/master.svg)](https://coveralls.io/github/yyle88/done?branch=main) +![Supported Go Versions](https://img.shields.io/badge/Go-1.22%2C%201.23-lightgrey.svg) +[![GitHub Release](https://img.shields.io/github/release/yyle88/done.svg)](https://github.com/yyle88/done/releases) +[![Go Report Card](https://goreportcard.com/badge/github.com/yyle88/done)](https://goreportcard.com/report/github.com/yyle88/done) -**Done** is a utility package designed to simplify error handling in Go projects, especially in informal or small-scale applications. It provides a set of functions and types to reduce the verbosity of error checking and handling by using assertions for successful operations. This package can help you avoid repetitive `if err != nil` checks and allow your code to be cleaner, more readable, and faster to write. +# Done - Simple Error Handling in Go + +**Done** allows you to focus on your business logic without repetitive `if err != nil` patterns. + +when you write logic: + +``` +if err := run(); err != nil{ + panic(err) +} +``` + +then you can use done: + +``` +done.Done(run()) +``` + +## CHINESE README -## README [中文说明](README.zh.md) +--- + ## Features -- **Simplified error handling:** Instead of explicitly checking for errors at every step, you can use assertions to handle errors automatically. -- **Supports multiple return values:** Effectively handles functions that return both a result and an error. -- **Reduces boilerplate code:** By using short, meaningful function calls, you can skip error checks and focus on your business logic. +- **Simple error handling**: Handle errors quickly with simple functions. +- **Supports multiple results**: Works well with functions that return a value and an error type. +- **Less repeated code**: Replace repeated error checks with short and clear functions. + +--- ## Installation @@ -17,40 +43,72 @@ go get github.com/yyle88/done ``` +--- + ## How It Works -This package introduces several types and functions that make error handling more concise. The core idea is to wrap the error check in an assertion, allowing you to proceed with the result if no error occurs. +The **Done** package wraps error checking into easy-to-use assertions, enabling you to handle errors while focusing on the success path of code. -### Core Types +--- -- `Ve[V any]`: A type that holds a value and an error. Provides methods to handle errors like `Done`, `Must`, and `Soft`. -- `Vpe[V any]`: A type for pointer values, with extended methods such as `Sure`, `Nice`, `Good`, and more. -- `Vce[V comparable]`: A type for comparable values that provides methods like `Same`, `Diff`, `Is`, `Equals`, etc., to handle value comparisons in error-prone scenarios. +## Core Types -### Key Functions +| Type | Description | +|-------------------------|-------------------------------------------------------------------------------| +| **`Ve[V any]`** | Holds a value and an error. Provides methods like `Done`, `Must`, and `Soft`. | +| **`Vpe[V any]`** | For pointer values, includes methods such as `Sure`, `Nice`, and `Good`. | +| **`Vce[V comparable]`** | For comparable values, provides methods like `Same`, `Diff`, and `Equals`. | -- `Done`: Checks if there is an error, panicking if one exists. -- `Must`: Similar to `Done`, but is more expressive of its intent to assert the error is `nil` and return the value. -- `Soft`: Logs a warning if there is an error but does not panic. -- `Fata`: Panics and logs the error at the "Fatal" level. -- `EExt`: Exits the program with a specific exit code if an error occurs, after printing the error in RED. +--- + +## Key Functions -### Example Usage +| Function | Description | +|------------|---------------------------------------------------| +| **`Done`** | Panics if an error exists. | +| **`Must`** | Ensures the error is `nil` and returns the value. | +| **`Soft`** | Logs a warning for errors but does not panic. | +| **`Fata`** | Logs the error at a "fatal" level and panics. | -Here is an example code: +--- + +## Functionality Summary + +| Category | Functions | Description | +|-------------------------|--------------------------------|-------------------------------------------------------------------------| +| **Error Handling** | `Done`, `Must`, `Soft` | Panics on error or handles it in a specific way. | +| **Result Validation** | `Sure`, `Nice`, `Some` | Ensures the result is not zero and returns it. | +| **Result Validation** | `Good`, `Fine`, `Safe` | Ensures the result is not zero without returning it. | +| **Zero Value Checking** | `Zero`, `None`, `Void` | Ensures the result is the zero value of its type. | +| **Value Comparisons** | `Same`, `Diff`, `Is`, `Equals` | Checks if values are the same, different, or match specific conditions. | + +--- + +## Advanced Error Handling + +| Utility | Description | +|-----------|-------------------------------------------------------------------------------------------| +| **`Vce`** | For comparable values, includes methods like `Same`, `Diff`, `Is`, and `Equals`. | +| **`Vse`** | For string operations, includes methods like `HasPrefix`, `HasSuffix`, and `Contains`. | +| **`Vne`** | For numeric operations, includes methods like `Gt` (greater than), `Lt` (less than), etc. | + +--- + +## Example Usage + +### Standard Error Handling ```go package main import ( - "fmt" - "github.com/yyle88/done" + "fmt" ) func main() { xyz, err := NewXyz() if err != nil { - panic(err) // Handle errors manually / 手动处理错误 + panic(err) // Handle errors manually } abc, err := xyz.Abc() if err != nil { @@ -64,14 +122,14 @@ func main() { } ``` -Here is how you would use the package to handle errors in a typical Go application: +### Using Done ```go package main import ( - "fmt" - "github.com/yyle88/done" + "fmt" + "github.com/yyle88/done" ) func main() { @@ -82,13 +140,13 @@ func main() { } ``` -See [demo1](internal/demos/demo1/main.go) +This approach simplifies the code by chaining function calls with error handling assertions. -In this example, the errors are checked and handled inline, allowing you to chain function calls without cluttering the code with repetitive error checks. +--- -### Chaining Operations +## Chaining Operations -Here is an example code: +### Without Done ```go package main @@ -98,26 +156,25 @@ import ( "strconv" "github.com/pkg/errors" - "github.com/yyle88/done" ) func main() { - snu, err := fetch() + stringNum, err := fetch() if err != nil { - panic(err) // Handle error manually / 手动处理错误 + panic(err) } - num, err := toInt(snu) + num, err := toInt(stringNum) if err != nil { panic(err) } - if !(num > 0) { - panic(errors.New("num is not > 0")) + if num <= 0 { + panic(errors.New("num <= 0")) } fmt.Println(num) } ``` -You can chain multiple function calls with error handling assertions in a single line: +### With Done ```go package main @@ -126,169 +183,37 @@ import ( "fmt" "strconv" - "github.com/pkg/errors" "github.com/yyle88/done" ) func main() { - num := done.VNE( toInt( done.VCE(fetch()).Nice() ) ).Gt(0) + num := done.VNE(toInt(done.VCE(fetch()).Nice())).Gt(0) fmt.Println(num) } ``` -See [demo2](internal/demos/demo2/main.go) +By using **Done**, you eliminate repetitive error checks and enable inline assertions for conditions, resulting in cleaner and more maintainable code. -This way, you can check if the error exists at each step and continue with the result without writing long error-handling logic. - -### Example NPC - -This section demonstrates how you can simplify error handling and result validation using the `done` package. - -By using `done.V1`, `done.P2`, and `done.C3`, you can reduce the complexity of your error checks and nil checks, making your code more readable. - -#### Example NPC 1 (nv): Checking Results from `run1()` - -Before using `done.V1`, we would have to manually check the error and handle nil values for the result: - -```go -a, err := run1() -if err != nil { - panic(err) // If an error occurs, trigger a panic -} -fmt.Println(a) // Output the result -``` - -With `done.V1`, you can perform the same checks in a cleaner, more concise way: - -```go -a := done.V1(run1()) // done.V1 handles error checking -fmt.Println(a) // Output the result -``` - -see [code](nv.go) see [case](nv_test.go) - -#### Example NPC 2 (np): Handling Multiple Results from `run2()` - -For functions that return multiple values, such as `run2()`, you can use a similar approach: - -```go -a, b, err := run2() -if err != nil { - panic(err) // If an error occurs, trigger a panic -} -if a == nil { - panic("a is nil") // If 'a' is nil, trigger panic -} -if b == nil { - panic("b is nil") // If 'b' is nil, trigger panic -} -fmt.Println(a, b) // Output both 'a' and 'b' -``` - -With `done.P2`, the error handling and nil checks are simplified: - -```go -a, b := done.P2(run2()) // done.P2 simplifies error checking and nil validation -fmt.Println(a, b) // Output both 'a' and 'b' -``` - -see [code](np.go) see [case](np_test.go) - -#### Example NPC 3 (nc): Handling Multiple Results from `run3()` - -For functions that return even more values, like `run3()`, you can extend this pattern: - -```go -a, b, c, err := run3() -if err != nil { - panic(err) // If an error occurs, trigger a panic -} -if a == 0 { - panic("a is zero") // If 'a' is zero, trigger panic -} -if b == "" { - panic("b is zero") // If 'b' is zero, trigger panic -} -if c == zero { - panic("c is zero") // If 'c' is zero, trigger panic -} -fmt.Println(a, b, c) // Output 'a', 'b', and 'c' -``` - -Using `done.C3` simplifies error handling and validation for multiple results: - -```go -a, b, c := done.C3(run3()) // done.C3 simplifies error checking and no-zero validation -fmt.Println(a, b, c) // Output 'a', 'b', and 'c' -``` - -see [code](nc.go) see [case](nc_test.go) - -See [demo3](internal/demos/demo3/main.go) - -This way you can avoid checking whether the return value has errors or null values, which is very convenient. - -There are also these methods that can provide additional convenience. - -`done.P1() - done.P9()` - -`done.C1() - done.C9()` - -`done.V1() - done.V9()` - -This avoids always checking if there are errors in the return values. - -## Usage Scenarios - -This package is ideal for projects where: - -- You want a concise error handling pattern. -- You are working in small, informal projects where errors are highly unlikely. -- You are okay with using panics for error handling in places where failure is considered unexpected and non-recoverable. - -**Important:** Although this package simplifies error handling, be mindful of using panics in production environments. It's suitable for scenarios where failure is extremely rare, such as development, testing, or specific low-risk situations. - -## Functionality Summary - -The utility functions provided by **Done** are based on different approaches to error handling: - -- **Done**: Only checks if `err != nil` and panics. -- **Sure/Nice/Some**: Ensures that the result is not zero (i.e., not `0`, `false`, `nil`, or an empty slice). -- **Good/Fine/Safe**: Verifies that the result is not zero but only checks it (without returning the result). -- **Zero/None/Void**: Ensures that the result is zero (i.e., the zero value of its type). -- **Same/Diff**: Ensures the result is the same or different as the expected value. - -## Common Functions - -- `Done`: Checks and panics if the error exists. -- `Sure/Nice/Some`: Ensures the result is not zero and returns it. -- `Good/Fine/Safe`: Ensures the result is not zero without returning it. -- `Zero/None/Void`: Ensures the result is zero and returns it. - -## Advanced Error Handling - -In cases where you need more complex logic, such as comparing values or checking conditions, you can use the following functions: - -- **Vce (Comparable + Errors)**: Check if two comparable values are the same or different using `Same`, `Diff`, `Is`, and `Equals`. -- **Vse (String + Errors)**: Check if a string matches conditions like `HasPrefix`, `HasSuffix`, or `Contains`. -- **Vne (Numerical + Errors)**: Check if a numeric value meets conditions like `Gt`, `Lt`, `Gte`, or `Lte`. +--- ## Conclusion -The **Done** package is a powerful and concise utility for error handling, especially in informal projects or small-scale applications. It helps you reduce boilerplate code, simplify error checks, and focus on the core logic of your application. +The **Done** package is a powerful tool for simplifying error handling, especially in informal or small-scale projects. It helps reduce boilerplate, makes error handling concise, and lets you focus on writing clean and efficient business logic. + +**Give it a try and share your feedback!** -**Give it a try, and let me know what you think!** +--- ## License -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. --- -## Give stars +## Contribute and Support -Feel free to contribute or improve the package! Your stars and pull requests are welcome. +Welcome to contribute to this project by submitting pull requests or reporting issues. -## Thank You +If you find this package helpful, give it a star on GitHub! -If you find this package valuable, give it a star on GitHub! Thank you!!! +**Thank you for your support!** diff --git a/README.zh.md b/README.zh.md index 44cd56c..37dccf3 100644 --- a/README.zh.md +++ b/README.zh.md @@ -1,79 +1,212 @@ -# done -package name "done" means function() return success. also means "assert". +# Done - 简化 Go 中的错误处理 -most of the time we write a go code, we need to handle the error return value. +**Done** 让你摆脱重复的 `if err != nil` 模式,更专注于业务逻辑。 -while the error handling logic wastes a lot of time and code lines. +当你写如下逻辑时: -``` -res, err := xxx() -if err != nil { - fatal(...) -} -if res == wrong-value { - panic(...) -} -// next logic -num, err := yyy(res) //use the res as an arg to call this function -if err != nil { - fatal(...) -} -if num <= 0 { - panic(...) +```go +if err := run(); err != nil { +panic(err) } -// then use the num in next logic ``` -so why not just panic when an error occurs(especially in small informal projects). +使用 Done 简化为: -so this utils can help some developers to override/rush/skip/ignore this problem. +```go +done.Done(run()) ``` -res := done.VCE(xxx()).Nice() -num := done.VCE(yyy(res)).Gt(0) -// then use the num in next logic -``` -so it can write in one line. -``` -num := done.VCE( yyy( done.VCE(xxx()).Nice() ) ).Gt(0) -// then use the num in next logic -``` -a ha ha ha! a genius design. -这个包的主要功能就是断言 "assert", 让你在99.99%不会出错的地方直接用个断言代替 err != nil 的错误处理,而且对于返回 res, err 两个返回值的函数非常有效。 +## 英文文档 -通常我们调用第三方包时,往往就是 `cli, err := xx.NewXx()` 接下来判断没有错误,在调用 `res, err:= cli.Abc()` 的操作,接下来使用 `res.Xyz` 获得信息,但这个函数依然可能是会返回个错误的,毕竟根据go的标准,或者说习惯,err都是一层一层向外返回的。 +[English README](README.md) -我当然知道我们开发代码需要遵守规范,但是,在某些非正式的场景里,我们确实希望代码能尽量短些我们就可以使用 -``` -cli := done.VCE( xx.NewXx() ).Nice() -xyz := done.VCE( cli.Abc() ).Nice().Xyz +--- + +## 特性 + +- **简单的错误处理**:快速处理错误,使用简单的函数。 +- **支持多个返回值**:适用于返回值和错误类型的函数。 +- **减少重复的代码**:用简洁明了的函数代替重复的错误检查。 + +--- + +## 安装 + +```bash +go get github.com/yyle88/done ``` -这样确实是能带来极大的便利。 -活学活用,别太死板,而且像 gin 和 kratos 框架在 HandleFunc 和 service 层面通常都是有 recover middleware 的,在几乎不可能出错的地方用断言也没啥问题。 +--- + +## 工作原理 + +**Done** 包将错误检查封装为易用的断言工具,帮助你专注于代码的成功路径,而不是错误处理的细节。 + +--- + +## 核心类型 + +| 类型 | 描述 | +|-------------------------|-------------------------------------------| +| **`Ve[V any]`** | 包含一个值和一个错误,提供 `Done`、`Must` 和 `Soft` 等操作。 | +| **`Vpe[V any]`** | 处理指针值,包含 `Sure`、`Nice` 和 `Good` 等操作。 | +| **`Vce[V comparable]`** | 用于可比较值,提供 `Same`、`Diff` 和 `Equals` 等操作。 | + +--- + +## 核心函数 + +| 函数 | 描述 | +|------------|--------------------| +| **`Done`** | 如果存在错误则触发 panic。 | +| **`Must`** | 确保错误为 nil 并返回值。 | +| **`Soft`** | 记录警告错误,但不触发 panic。 | +| **`Fata`** | 记录错误日志并触发 panic。 | + +--- + +## 功能概览 + +| 类别 | 函数 | 描述 | +|----------|------------------------|-----------------------| +| **错误处理** | `Done`, `Must`, `Soft` | 对错误进行 panic 或特定方式的处理。 | +| **结果验证** | `Sure`, `Nice`, `Some` | 确保结果非零值并返回。 | +| **结果验证** | `Good`, `Fine`, `Safe` | 确保结果非零值但不返回结果。 | +| **零值检查** | `Zero`, `None`, `Void` | 确保结果为其类型的零值。 | +| **量值比较** | `Same`, `Diff`, `Is` | 检查值是否相同、不同或符合特定条件。 | + +--- + +## 高级错误处理 + +| 工具 | 描述 | +|-----------|------------------------------------------------------| +| **`Vce`** | 针对可比较值,提供 `Same`、`Diff`、`Is` 和 `Equals` 等方法。 | +| **`Vse`** | 针对字符串操作,提供 `HasPrefix`、`HasSuffix` 和 `Contains` 等方法。 | +| **`Vne`** | 针对数字操作,提供 `Gt`(大于)、`Lt`(小于)等方法。 | + +--- + +## 示例用法 + +### 标准错误处理 + +```go +package main -该 panic 就 panic 吧。 +import ( + "fmt" +) -code: +func main() { + xyz, err := NewXyz() + if err != nil { + panic(err) // 手动处理错误 + } + abc, err := xyz.Abc() + if err != nil { + panic(err) + } + uvw, err := abc.Uvw() + if err != nil { + panic(err) + } + fmt.Println(uvw.Message) +} ``` -v_e means check res, err and the result, check with some interface{}/any logic. -vae means check res, err and the result, check with array/slice logic. -vbe means check res, err and the result, check with bool logic. -vce means check res, err and the result, some comparable logic. -vse means check res, err and the result, some function: HasPrefix HasSuffix Contains -vne means check res, err and the result, some function: Gt Lt Gte Lte + +### 使用 Done + +```go +package main + +import ( + "fmt" + "github.com/yyle88/done" +) + +func main() { + xyz := done.VCE(NewXyz()).Nice() + abc := done.VCE(xyz.Abc()).Nice() + uvw := done.VCE(abc.Uvw()).Nice() + fmt.Println(uvw.Message) +} ``` -common function: +这种方法通过链式调用简化了代码,同时结合错误处理断言,使代码更简洁、易读。 + +--- + +## 链式操作 + +### 不使用 Done + +```go +package main + +import ( + "fmt" + "strconv" + + "github.com/pkg/errors" +) + +func main() { + stringNum, err := fetch() + if err != nil { + panic(err) + } + num, err := toInt(stringNum) + if err != nil { + panic(err) + } + if num <= 0 { + panic(errors.New("num <= 0")) + } + fmt.Println(num) +} ``` -Done means when param is (res, err) it only check if err is nil(logic is if err != nil {panic}), means success. -Sure/Nice/Some means error is nil and the result is not zero value(0/""/false/nil object/empty slice) and then return the res. -Good/Fine/Safe means error is nil and the result is not zero. only check. not return. -Zero/None/Void means error is nil and the result is zero value. + +### 使用 Done + +```go +package main + +import ( + "fmt" + "strconv" + + "github.com/yyle88/done" +) + +func main() { + num := done.VNE(toInt(done.VCE(fetch()).Nice())).Gt(0) + fmt.Println(num) +} ``` -使用几个同义词的目的是,这样开发者就可以根据自己的爱好自由选择,而几乎所有的单词都是四个字母的. +通过 **Done**,你可以消除重复的错误检查,用内联断言实现条件校验,使代码更整洁、可维护。 + +--- + +## 总结 + +**Done** 包是一个强大的工具,可以简化错误处理,特别适用于非正式或小型项目。它减少了模板代码的重复,使错误处理更简洁,让你专注于编写清晰高效的业务逻辑。 + +**试试看并分享你的反馈吧!** + +--- + +## 许可证 + +此项目基于 MIT 许可证。详细信息请参阅 [LICENSE](LICENSE) 文件。 + +--- + +## 贡献与支持 + +欢迎通过提交拉取请求或报告问题来为此项目做出贡献。 -当然也是为了让代码更简洁(其实是强迫症在作祟),但最终还是没能完全只用四个字母的单词(破功啦)。 +如果你觉得这个包有用,请在 GitHub 上给个星! -Give me stars. thank you!!! +**感谢你的支持!** diff --git a/utils_check.go b/check_func.go similarity index 69% rename from utils_check.go rename to check_func.go index 308079e..b8fe2fb 100644 --- a/utils_check.go +++ b/check_func.go @@ -1,9 +1,6 @@ package done import ( - "fmt" - "os" - "github.com/yyle88/zaplog" "go.uber.org/zap" ) @@ -36,13 +33,3 @@ func Fata(err error) { zaplog.LOGS.P1.Fatal("ERROR", zap.Error(err)) } } - -// EExt 逻辑相当于 if err != nil { os.Exit(code) } 也是出错时打印红色错误信息,接着退出系统 -func EExt(err error, code int) { - if err != nil { - var msg = fmt.Sprintf("\x1b[31;1m%s\x1b[0m", err) //红色打印 - fmt.Println(msg) - zaplog.LOGS.P1.Error("ERROR", zap.Error(err)) - os.Exit(code) - } -} diff --git a/utils_check_test.go b/check_func_test.go similarity index 81% rename from utils_check_test.go rename to check_func_test.go index f552dd1..60e6be4 100644 --- a/utils_check_test.go +++ b/check_func_test.go @@ -27,9 +27,3 @@ func TestFata(t *testing.T) { Fata(errors.New("123")) } } - -func TestEExt(t *testing.T) { - if false { - EExt(errors.New("123"), -1) - } -} diff --git a/go.mod b/go.mod index da39c00..9c2734b 100644 --- a/go.mod +++ b/go.mod @@ -4,15 +4,15 @@ go 1.22.6 require ( github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.9.0 - github.com/yyle88/zaplog v0.0.14 + github.com/stretchr/testify v1.10.0 + github.com/yyle88/zaplog v0.0.16 go.uber.org/zap v1.27.0 ) require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/yyle88/mutexmap v1.0.7 // indirect + github.com/yyle88/mutexmap v1.0.8 // indirect go.uber.org/multierr v1.11.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index f1bced4..636e758 100644 --- a/go.sum +++ b/go.sum @@ -10,12 +10,12 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yyle88/mutexmap v1.0.7 h1:i4inpmq0fEvwxG9XGunxBVQBt0eAZEWL7ezurkQifqY= -github.com/yyle88/mutexmap v1.0.7/go.mod h1:lAEDkpXe9iSU0/8L/SaXAQ6TUa+4A9nnl9OQ56zHEQY= -github.com/yyle88/zaplog v0.0.14 h1:AN7pcBbo+QsHU3jYdu6NJdhckZ5OsnCBB5Wf8xQpBz8= -github.com/yyle88/zaplog v0.0.14/go.mod h1:EVbOBQhJ0kn7dPa7bpJs/8zEY5N6XQS9SodeojwQmdE= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/yyle88/mutexmap v1.0.8 h1:VntAdXID5wbk211LZEPVK96jQBxIcfVIbQuk9cv3P/8= +github.com/yyle88/mutexmap v1.0.8/go.mod h1:QUYDuARLPlGj414kHewQ5tt8jkDxQXoai8H3C4Gg+yc= +github.com/yyle88/zaplog v0.0.16 h1:ZCxQhq3+nWeWMAXIzeA1EA4exRq5Pn8pXTpEw1GjyD4= +github.com/yyle88/zaplog v0.0.16/go.mod h1:0ct8Rh6uE5i9RG+xbH6d4/pyDBt9JmxBqHNCI+T4wiM= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= diff --git a/internal/demos/demo3/main.go b/internal/demos/demo3/main.go index 377dc59..5d056cd 100644 --- a/internal/demos/demo3/main.go +++ b/internal/demos/demo3/main.go @@ -7,100 +7,44 @@ import ( ) func main() { - // Directly checking the result of run1 with error handling - // 使用直接方法检查 run1 的结果并处理错误 - { - a, err := run1() - if err != nil { - panic(err) // If an error occurs, trigger a panic - // 如果发生错误,触发 panic - } - if a == nil { - panic("a is nil") // If 'a' is nil, trigger panic - // 如果 'a' 为 nil,触发 panic - } - fmt.Println(a) // Output the result - // 输出结果 - } - - // Using done.P1 for cleaner error handling and result validation - // 使用 done.P1 简化错误处理和结果验证 - { - a := done.P1(run1()) // done.P1 handles error checking and nil validation - // done.P1 处理错误检查和 nil 验证 - fmt.Println(a) // Output the result - // 输出结果 - } - - // Directly checking the result of run2 with error handling - // 使用直接方法检查 run2 的结果并处理错误 - { - a, b, err := run2() - if err != nil { - panic(err) // If an error occurs, trigger a panic - // 如果发生错误,触发 panic - } - if a == nil { - panic("a is nil") // If 'a' is nil, trigger panic - // 如果 'a' 为 nil,触发 panic - } - if b == nil { - panic("b is nil") // If 'b' is nil, trigger panic - // 如果 'b' 为 nil,触发 panic - } - fmt.Println(a, b) // Output both 'a' and 'b' - // 输出 'a' 和 'b' - } + // Directly checking the result of run with error handling + // 使用直接方法检查 run 的结果并处理错误 + demoLogic() // Using done.P2 for more concise error handling and result validation // 使用 done.P2 使错误处理和结果验证更简洁 - { - a, b := done.P2(run2()) // done.P2 simplifies error checking and validation - // done.P2 简化了错误检查和验证 - fmt.Println(a, b) // Output both 'a' and 'b' - // 输出 'a' 和 'b' - } + sameLogic() +} - // Directly checking the result of run3 with error handling - // 使用直接方法检查 run3 的结果并处理错误 - { - a, b, c, err := run3() - if err != nil { - panic(err) // If an error occurs, trigger a panic - // 如果发生错误,触发 panic - } - if a == nil { - panic("a is nil") // If 'a' is nil, trigger panic - // 如果 'a' 为 nil,触发 panic - } - if b == nil { - panic("b is nil") // If 'b' is nil, trigger panic - // 如果 'b' 为 nil,触发 panic - } - if c == nil { - panic("c is nil") // If 'c' is nil, trigger panic - // 如果 'c' 为 nil,触发 panic - } - fmt.Println(a, b, c) // Output 'a', 'b', and 'c' - // 输出 'a','b' 和 'c' +func demoLogic() { + a, b, err := run() + if err != nil { + panic(err) // If an error occurs, trigger a panic + // 如果发生错误,触发 panic } - - // Using done.P3 to simplify error handling and result validation for run3 - // 使用 done.P3 简化 run3 的错误处理和结果验证 - { - a, b, c := done.P3(run3()) // done.P3 simplifies error checking and validation - // done.P3 简化了错误检查和验证 - fmt.Println(a, b, c) // Output 'a', 'b', and 'c' - // 输出 'a','b' 和 'c' + if a == nil { + panic("a is nil") // If 'a' is nil, trigger panic + // 如果 'a' 为 nil,触发 panic + } + if b == nil { + panic("b is nil") // If 'b' is nil, trigger panic + // 如果 'b' 为 nil,触发 panic } + fmt.Println(a, b) // Output both 'a' and 'b' + // 输出 'a' 和 'b' +} + +func sameLogic() { + a, b := done.P2(run()) // done.P2 simplifies error checking and validation + // done.P2 简化了错误检查和验证 + fmt.Println(a, b) // Output both 'a' and 'b' + // 输出 'a' 和 'b' } // -------------------------- // Simulated business logic // -------------------------- -// Defining mock types for demonstration with fields -// 为演示定义模拟类型并添加字段 type A struct { ID int Name string @@ -111,25 +55,8 @@ type B struct { City string } -type C struct { - Price float64 - Code string -} - -// run1 simulates returning an instance of A and error -// run1 模拟返回 A 的实例和错误 -func run1() (*A, error) { - return &A{ID: 1, Name: "Alice"}, nil -} - -// run2 simulates returning instances of A and B, and error -// run2 模拟返回 A 和 B 的实例以及错误 -func run2() (*A, *B, error) { - return &A{ID: 1, Name: "Alice"}, &B{Age: 30, City: "New York"}, nil -} - -// run3 simulates returning instances of A, B, and C, and error -// run3 模拟返回 A, B 和 C 的实例以及错误 -func run3() (*A, *B, *C, error) { - return &A{ID: 1, Name: "Alice"}, &B{Age: 30, City: "New York"}, &C{Price: 100.5, Code: "XYZ123"}, nil +func run() (*A, *B, error) { + a := &A{ID: 1, Name: "Alice"} + b := &B{Age: 30, City: "New York"} + return a, b, nil } diff --git a/nc.go b/nc.go deleted file mode 100644 index b8e27bf..0000000 --- a/nc.go +++ /dev/null @@ -1,95 +0,0 @@ -package done - -func C0(err error) { - Must(err) -} - -func C1[T1 comparable](v1 T1, err error) T1 { - Must(err) - Nice(v1) - return v1 -} - -func C2[T1, T2 comparable](v1 T1, v2 T2, err error) (T1, T2) { - Must(err) - Nice(v1) - Nice(v2) - return v1, v2 -} - -func C3[T1, T2, T3 comparable](v1 T1, v2 T2, v3 T3, err error) (T1, T2, T3) { - Must(err) - Nice(v1) - Nice(v2) - Nice(v3) - return v1, v2, v3 -} - -func C4[T1, T2, T3, T4 comparable](v1 T1, v2 T2, v3 T3, v4 T4, err error) (T1, T2, T3, T4) { - Must(err) - Nice(v1) - Nice(v2) - Nice(v3) - Nice(v4) - return v1, v2, v3, v4 -} - -func C5[T1, T2, T3, T4, T5 comparable](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, err error) (T1, T2, T3, T4, T5) { - Must(err) - Nice(v1) - Nice(v2) - Nice(v3) - Nice(v4) - Nice(v5) - return v1, v2, v3, v4, v5 -} - -func C6[T1, T2, T3, T4, T5, T6 comparable](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, err error) (T1, T2, T3, T4, T5, T6) { - Must(err) - Nice(v1) - Nice(v2) - Nice(v3) - Nice(v4) - Nice(v5) - Nice(v6) - return v1, v2, v3, v4, v5, v6 -} - -func C7[T1, T2, T3, T4, T5, T6, T7 comparable](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, err error) (T1, T2, T3, T4, T5, T6, T7) { - Must(err) - Nice(v1) - Nice(v2) - Nice(v3) - Nice(v4) - Nice(v5) - Nice(v6) - Nice(v7) - return v1, v2, v3, v4, v5, v6, v7 -} - -func C8[T1, T2, T3, T4, T5, T6, T7, T8 comparable](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, v8 T8, err error) (T1, T2, T3, T4, T5, T6, T7, T8) { - Must(err) - Nice(v1) - Nice(v2) - Nice(v3) - Nice(v4) - Nice(v5) - Nice(v6) - Nice(v7) - Nice(v8) - return v1, v2, v3, v4, v5, v6, v7, v8 -} - -func C9[T1, T2, T3, T4, T5, T6, T7, T8, T9 comparable](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, v8 T8, v9 T9, err error) (T1, T2, T3, T4, T5, T6, T7, T8, T9) { - Must(err) - Nice(v1) - Nice(v2) - Nice(v3) - Nice(v4) - Nice(v5) - Nice(v6) - Nice(v7) - Nice(v8) - Nice(v9) - return v1, v2, v3, v4, v5, v6, v7, v8, v9 -} diff --git a/nc_test.go b/nc_test.go deleted file mode 100644 index b2e056a..0000000 --- a/nc_test.go +++ /dev/null @@ -1,133 +0,0 @@ -package done_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - "github.com/yyle88/done" -) - -func TestC0(t *testing.T) { - run := func() error { - return nil - } - - done.C0(run()) -} - -func TestC1(t *testing.T) { - run := func() (string, error) { - return "hello", nil - } - - v1 := done.C1(run()) - require.Equal(t, "hello", v1) -} - -func TestC2(t *testing.T) { - run := func() (int, float64, error) { - return 42, 3.14, nil - } - - v1, v2 := done.C2(run()) - require.Equal(t, 42, v1) - require.Equal(t, 3.14, v2) -} - -func TestC3(t *testing.T) { - run := func() (bool, byte, rune, error) { - return true, 'A', '中', nil - } - - v1, v2, v3 := done.C3(run()) - require.True(t, v1) - require.Equal(t, byte('A'), v2) - require.Equal(t, '中', v3) -} - -func TestC4(t *testing.T) { - run := func() (string, int, uint, float32, error) { - return "world", -7, 7, 1.23, nil - } - - v1, v2, v3, v4 := done.C4(run()) - require.Equal(t, "world", v1) - require.Equal(t, -7, v2) - require.Equal(t, uint(7), v3) - require.Equal(t, float32(1.23), v4) -} - -func TestC5(t *testing.T) { - run := func() (uint8, uint16, uint32, uint64, string, error) { - return 8, 16, 32, 64, "test", nil - } - - v1, v2, v3, v4, v5 := done.C5(run()) - require.Equal(t, uint8(8), v1) - require.Equal(t, uint16(16), v2) - require.Equal(t, uint32(32), v3) - require.Equal(t, uint64(64), v4) - require.Equal(t, "test", v5) -} - -func TestC6(t *testing.T) { - run := func() (float64, complex64, complex128, bool, string, int, error) { - return 6.28, complex(1, 2), complex(3, 4), true, "check", -1, nil - } - - v1, v2, v3, v4, v5, v6 := done.C6(run()) - require.Equal(t, 6.28, v1) - require.Equal(t, complex64(complex(1, 2)), v2) - require.Equal(t, complex(3, 4), v3) - require.True(t, v4) - require.Equal(t, "check", v5) - require.Equal(t, -1, v6) -} - -func TestC7(t *testing.T) { - run := func() (uint, uint8, uint16, uint32, uint64, int, int8, error) { - return 1, 2, 3, 4, 5, 6, 7, nil - } - - v1, v2, v3, v4, v5, v6, v7 := done.C7(run()) - require.Equal(t, uint(1), v1) - require.Equal(t, uint8(2), v2) - require.Equal(t, uint16(3), v3) - require.Equal(t, uint32(4), v4) - require.Equal(t, uint64(5), v5) - require.Equal(t, 6, v6) - require.Equal(t, int8(7), v7) -} - -func TestC8(t *testing.T) { - run := func() (string, rune, byte, bool, float32, float64, int32, int64, error) { - return "go", '中', 'B', true, 2.71, 1.618, -32, -64, nil - } - - v1, v2, v3, v4, v5, v6, v7, v8 := done.C8(run()) - require.Equal(t, "go", v1) - require.Equal(t, '中', v2) - require.Equal(t, byte('B'), v3) - require.True(t, v4) - require.Equal(t, float32(2.71), v5) - require.Equal(t, 1.618, v6) - require.Equal(t, int32(-32), v7) - require.Equal(t, int64(-64), v8) -} - -func TestC9(t *testing.T) { - run := func() (string, uint8, int16, uint32, int64, float32, float64, complex64, complex128, error) { - return "done", 255, -16, 32, -64, 3.14, 2.71, complex(5, 6), complex(7, 8), nil - } - - v1, v2, v3, v4, v5, v6, v7, v8, v9 := done.C9(run()) - require.Equal(t, "done", v1) - require.Equal(t, uint8(255), v2) - require.Equal(t, int16(-16), v3) - require.Equal(t, uint32(32), v4) - require.Equal(t, int64(-64), v5) - require.Equal(t, float32(3.14), v6) - require.Equal(t, 2.71, v7) - require.Equal(t, complex64(complex(5, 6)), v8) - require.Equal(t, complex(7, 8), v9) -} diff --git a/np.go b/np.go deleted file mode 100644 index 5a18ce5..0000000 --- a/np.go +++ /dev/null @@ -1,95 +0,0 @@ -package done - -func P0(err error) { - Must(err) -} - -func P1[T1 any](v1 *T1, err error) *T1 { - Must(err) - Full(v1) - return v1 -} - -func P2[T1, T2 any](v1 *T1, v2 *T2, err error) (*T1, *T2) { - Must(err) - Full(v1) - Full(v2) - return v1, v2 -} - -func P3[T1, T2, T3 any](v1 *T1, v2 *T2, v3 *T3, err error) (*T1, *T2, *T3) { - Must(err) - Full(v1) - Full(v2) - Full(v3) - return v1, v2, v3 -} - -func P4[T1, T2, T3, T4 any](v1 *T1, v2 *T2, v3 *T3, v4 *T4, err error) (*T1, *T2, *T3, *T4) { - Must(err) - Full(v1) - Full(v2) - Full(v3) - Full(v4) - return v1, v2, v3, v4 -} - -func P5[T1, T2, T3, T4, T5 any](v1 *T1, v2 *T2, v3 *T3, v4 *T4, v5 *T5, err error) (*T1, *T2, *T3, *T4, *T5) { - Must(err) - Full(v1) - Full(v2) - Full(v3) - Full(v4) - Full(v5) - return v1, v2, v3, v4, v5 -} - -func P6[T1, T2, T3, T4, T5, T6 any](v1 *T1, v2 *T2, v3 *T3, v4 *T4, v5 *T5, v6 *T6, err error) (*T1, *T2, *T3, *T4, *T5, *T6) { - Must(err) - Full(v1) - Full(v2) - Full(v3) - Full(v4) - Full(v5) - Full(v6) - return v1, v2, v3, v4, v5, v6 -} - -func P7[T1, T2, T3, T4, T5, T6, T7 any](v1 *T1, v2 *T2, v3 *T3, v4 *T4, v5 *T5, v6 *T6, v7 *T7, err error) (*T1, *T2, *T3, *T4, *T5, *T6, *T7) { - Must(err) - Full(v1) - Full(v2) - Full(v3) - Full(v4) - Full(v5) - Full(v6) - Full(v7) - return v1, v2, v3, v4, v5, v6, v7 -} - -func P8[T1, T2, T3, T4, T5, T6, T7, T8 any](v1 *T1, v2 *T2, v3 *T3, v4 *T4, v5 *T5, v6 *T6, v7 *T7, v8 *T8, err error) (*T1, *T2, *T3, *T4, *T5, *T6, *T7, *T8) { - Must(err) - Full(v1) - Full(v2) - Full(v3) - Full(v4) - Full(v5) - Full(v6) - Full(v7) - Full(v8) - return v1, v2, v3, v4, v5, v6, v7, v8 -} - -func P9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](v1 *T1, v2 *T2, v3 *T3, v4 *T4, v5 *T5, v6 *T6, v7 *T7, v8 *T8, v9 *T9, err error) (*T1, *T2, *T3, *T4, *T5, *T6, *T7, *T8, *T9) { - Must(err) - Full(v1) - Full(v2) - Full(v3) - Full(v4) - Full(v5) - Full(v6) - Full(v7) - Full(v8) - Full(v9) - return v1, v2, v3, v4, v5, v6, v7, v8, v9 -} diff --git a/np_test.go b/np_test.go deleted file mode 100644 index ed1cc2a..0000000 --- a/np_test.go +++ /dev/null @@ -1,178 +0,0 @@ -package done_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - "github.com/yyle88/done" -) - -func TestP0(t *testing.T) { - run := func() error { - return nil - } - - done.P0(run()) -} - -func TestP1(t *testing.T) { - run := func() (*string, error) { - v1 := "hello" - return &v1, nil - } - - p1 := done.P1(run()) - require.Equal(t, "hello", *p1) -} - -func TestP2(t *testing.T) { - run := func() (*int, *float64, error) { - v1 := 42 - v2 := 3.14 - return &v1, &v2, nil - } - - v1, v2 := done.P2(run()) - require.Equal(t, 42, *v1) - require.Equal(t, 3.14, *v2) -} - -func TestP3(t *testing.T) { - run := func() (*string, *int, *bool, error) { - v1 := "test" - v2 := 100 - v3 := true - return &v1, &v2, &v3, nil - } - - v1, v2, v3 := done.P3(run()) - require.Equal(t, "test", *v1) - require.Equal(t, 100, *v2) - require.Equal(t, true, *v3) -} - -func TestP4(t *testing.T) { - run := func() (*int, *float64, *bool, *string, error) { - v1 := 42 - v2 := 3.14 - v3 := false - v4 := "world" - return &v1, &v2, &v3, &v4, nil - } - - v1, v2, v3, v4 := done.P4(run()) - require.Equal(t, 42, *v1) - require.Equal(t, 3.14, *v2) - require.Equal(t, false, *v3) - require.Equal(t, "world", *v4) -} - -func TestP5(t *testing.T) { - run := func() (*string, *int, *bool, *float64, *rune, error) { - v1 := "test" - v2 := 123 - v3 := true - v4 := 2.718 - v5 := 'a' - return &v1, &v2, &v3, &v4, &v5, nil - } - - v1, v2, v3, v4, v5 := done.P5(run()) - require.Equal(t, "test", *v1) - require.Equal(t, 123, *v2) - require.Equal(t, true, *v3) - require.Equal(t, 2.718, *v4) - require.Equal(t, 'a', *v5) -} - -func TestP6(t *testing.T) { - run := func() (*float64, *int, *string, *bool, *rune, *int64, error) { - v1 := 3.14 - v2 := 42 - v3 := "hello" - v4 := true - v5 := 'x' - v6 := int64(100000) - return &v1, &v2, &v3, &v4, &v5, &v6, nil - } - - v1, v2, v3, v4, v5, v6 := done.P6(run()) - require.Equal(t, 3.14, *v1) - require.Equal(t, 42, *v2) - require.Equal(t, "hello", *v3) - require.Equal(t, true, *v4) - require.Equal(t, 'x', *v5) - require.Equal(t, int64(100000), *v6) -} - -func TestP7(t *testing.T) { - run := func() (*bool, *string, *int, *float64, *rune, *int64, *uint32, error) { - v1 := true - v2 := "world" - v3 := 50 - v4 := 1.618 - v5 := 'y' - v6 := int64(200000) - v7 := uint32(300) - return &v1, &v2, &v3, &v4, &v5, &v6, &v7, nil - } - - v1, v2, v3, v4, v5, v6, v7 := done.P7(run()) - require.Equal(t, true, *v1) - require.Equal(t, "world", *v2) - require.Equal(t, 50, *v3) - require.Equal(t, 1.618, *v4) - require.Equal(t, 'y', *v5) - require.Equal(t, int64(200000), *v6) - require.Equal(t, uint32(300), *v7) -} - -func TestP8(t *testing.T) { - run := func() (*string, *int, *bool, *float64, *rune, *int64, *uint32, *uint8, error) { - v1 := "abc" - v2 := 999 - v3 := false - v4 := 0.577 - v5 := 'z' - v6 := int64(500000) - v7 := uint32(400) - v8 := uint8(255) - return &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, nil - } - - v1, v2, v3, v4, v5, v6, v7, v8 := done.P8(run()) - require.Equal(t, "abc", *v1) - require.Equal(t, 999, *v2) - require.Equal(t, false, *v3) - require.Equal(t, 0.577, *v4) - require.Equal(t, 'z', *v5) - require.Equal(t, int64(500000), *v6) - require.Equal(t, uint32(400), *v7) - require.Equal(t, uint8(255), *v8) -} - -func TestP9(t *testing.T) { - run := func() (*string, *int, *bool, *float64, *rune, *int64, *uint32, *uint8, *uint64, error) { - v1 := "final" - v2 := 888 - v3 := true - v4 := 2.718 - v5 := 'p' - v6 := int64(900000) - v7 := uint32(500) - v8 := uint8(100) - v9 := uint64(1000000) - return &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, nil - } - - v1, v2, v3, v4, v5, v6, v7, v8, v9 := done.P9(run()) - require.Equal(t, "final", *v1) - require.Equal(t, 888, *v2) - require.Equal(t, true, *v3) - require.Equal(t, 2.718, *v4) - require.Equal(t, 'p', *v5) - require.Equal(t, int64(900000), *v6) - require.Equal(t, uint32(500), *v7) - require.Equal(t, uint8(100), *v8) - require.Equal(t, uint64(1000000), *v9) -} diff --git a/nv.go b/nv.go deleted file mode 100644 index 2029dbe..0000000 --- a/nv.go +++ /dev/null @@ -1,50 +0,0 @@ -package done - -func V0(err error) { - Must(err) -} - -func V1[T1 any](v1 T1, err error) T1 { - Must(err) - return v1 -} - -func V2[T1, T2 any](v1 T1, v2 T2, err error) (T1, T2) { - Must(err) - return v1, v2 -} - -func V3[T1, T2, T3 any](v1 T1, v2 T2, v3 T3, err error) (T1, T2, T3) { - Must(err) - return v1, v2, v3 -} - -func V4[T1, T2, T3, T4 any](v1 T1, v2 T2, v3 T3, v4 T4, err error) (T1, T2, T3, T4) { - Must(err) - return v1, v2, v3, v4 -} - -func V5[T1, T2, T3, T4, T5 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, err error) (T1, T2, T3, T4, T5) { - Must(err) - return v1, v2, v3, v4, v5 -} - -func V6[T1, T2, T3, T4, T5, T6 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, err error) (T1, T2, T3, T4, T5, T6) { - Must(err) - return v1, v2, v3, v4, v5, v6 -} - -func V7[T1, T2, T3, T4, T5, T6, T7 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, err error) (T1, T2, T3, T4, T5, T6, T7) { - Must(err) - return v1, v2, v3, v4, v5, v6, v7 -} - -func V8[T1, T2, T3, T4, T5, T6, T7, T8 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, v8 T8, err error) (T1, T2, T3, T4, T5, T6, T7, T8) { - Must(err) - return v1, v2, v3, v4, v5, v6, v7, v8 -} - -func V9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](v1 T1, v2 T2, v3 T3, v4 T4, v5 T5, v6 T6, v7 T7, v8 T8, v9 T9, err error) (T1, T2, T3, T4, T5, T6, T7, T8, T9) { - Must(err) - return v1, v2, v3, v4, v5, v6, v7, v8, v9 -} diff --git a/nv_test.go b/nv_test.go deleted file mode 100644 index d5d1f02..0000000 --- a/nv_test.go +++ /dev/null @@ -1,133 +0,0 @@ -package done_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - "github.com/yyle88/done" -) - -func TestV0(t *testing.T) { - run := func() error { - return nil - } - - done.V0(run()) -} - -func TestV1(t *testing.T) { - run := func() (string, error) { - return "a", nil - } - - v1 := done.V1(run()) - require.Equal(t, "a", v1) -} - -func TestV2(t *testing.T) { - run := func() (string, uint64, error) { - return "a", 2, nil - } - - v1, v2 := done.V2(run()) - require.Equal(t, "a", v1) - require.Equal(t, uint64(2), v2) -} - -func TestV3(t *testing.T) { - run := func() (string, uint64, rune, error) { - return "a", 2, 'x', nil - } - - v1, v2, v3 := done.V3(run()) - require.Equal(t, "a", v1) - require.Equal(t, uint64(2), v2) - require.Equal(t, 'x', v3) -} - -func TestV4(t *testing.T) { - run := func() (string, uint64, rune, int32, error) { - return "a", 2, 'x', 42, nil - } - - v1, v2, v3, v4 := done.V4(run()) - require.Equal(t, "a", v1) - require.Equal(t, uint64(2), v2) - require.Equal(t, 'x', v3) - require.Equal(t, int32(42), v4) -} - -func TestV5(t *testing.T) { - run := func() (string, uint64, rune, int32, float64, error) { - return "a", 2, 'x', 42, 3.14, nil - } - - v1, v2, v3, v4, v5 := done.V5(run()) - require.Equal(t, "a", v1) - require.Equal(t, uint64(2), v2) - require.Equal(t, 'x', v3) - require.Equal(t, int32(42), v4) - require.Equal(t, 3.14, v5) -} - -func TestV6(t *testing.T) { - run := func() (string, uint64, rune, int32, float64, bool, error) { - return "a", 2, 'x', 42, 3.14, true, nil - } - - v1, v2, v3, v4, v5, v6 := done.V6(run()) - require.Equal(t, "a", v1) - require.Equal(t, uint64(2), v2) - require.Equal(t, 'x', v3) - require.Equal(t, int32(42), v4) - require.Equal(t, 3.14, v5) - require.Equal(t, true, v6) -} - -func TestV7(t *testing.T) { - run := func() (string, uint64, rune, int32, float64, bool, byte, error) { - return "a", 2, 'x', 42, 3.14, true, byte(255), nil - } - - v1, v2, v3, v4, v5, v6, v7 := done.V7(run()) - require.Equal(t, "a", v1) - require.Equal(t, uint64(2), v2) - require.Equal(t, 'x', v3) - require.Equal(t, int32(42), v4) - require.Equal(t, 3.14, v5) - require.Equal(t, true, v6) - require.Equal(t, byte(255), v7) -} - -func TestV8(t *testing.T) { - run := func() (string, uint64, rune, int32, float64, bool, byte, int64, error) { - return "a", 2, 'x', 42, 3.14, true, byte(255), int64(123456789), nil - } - - v1, v2, v3, v4, v5, v6, v7, v8 := done.V8(run()) - require.Equal(t, "a", v1) - require.Equal(t, uint64(2), v2) - require.Equal(t, 'x', v3) - require.Equal(t, int32(42), v4) - require.Equal(t, 3.14, v5) - require.Equal(t, true, v6) - require.Equal(t, byte(255), v7) - require.Equal(t, int64(123456789), v8) -} - -func TestV9(t *testing.T) { - run := func() (string, uint64, rune, int32, float64, bool, byte, int64, uint32, error) { - return "a", 2, 'x', 42, 3.14, true, byte(255), int64(123456789), uint32(987654321), nil - } - - v1, v2, v3, v4, v5, v6, v7, v8, v9 := done.V9(run()) - require.Equal(t, "a", v1) - require.Equal(t, uint64(2), v2) - require.Equal(t, 'x', v3) - require.Equal(t, int32(42), v4) - require.Equal(t, 3.14, v5) - require.Equal(t, true, v6) - require.Equal(t, byte(255), v7) - require.Equal(t, int64(123456789), v8) - require.Equal(t, uint32(987654321), v9) -} diff --git a/rese.go b/rese.go new file mode 100644 index 0000000..cd3c0f2 --- /dev/null +++ b/rese.go @@ -0,0 +1,49 @@ +package done + +func V0(err error) { + Done(err) +} + +func V1[T1 any](v1 T1, err error) T1 { + Done(err) + return v1 +} + +func V2[T1, T2 any](v1 T1, v2 T2, err error) (T1, T2) { + Done(err) + return v1, v2 +} + +func P0(err error) { + Done(err) +} + +func P1[T1 any](v1 *T1, err error) *T1 { + Done(err) + Full(v1) + return v1 +} + +func P2[T1, T2 any](v1 *T1, v2 *T2, err error) (*T1, *T2) { + Done(err) + Full(v1) + Full(v2) + return v1, v2 +} + +func C0(err error) { + Done(err) +} + +func C1[T1 comparable](v1 T1, err error) T1 { + Done(err) + Nice(v1) + return v1 +} + +func C2[T1, T2 comparable](v1 T1, v2 T2, err error) (T1, T2) { + Done(err) + Nice(v1) + Nice(v2) + return v1, v2 +} diff --git a/rese_test.go b/rese_test.go new file mode 100644 index 0000000..1204183 --- /dev/null +++ b/rese_test.go @@ -0,0 +1,92 @@ +package done_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/yyle88/done" +) + +func TestV0(t *testing.T) { + run := func() error { + return nil + } + + done.V0(run()) +} + +func TestV1(t *testing.T) { + run := func() (string, error) { + return "a", nil + } + + v1 := done.V1(run()) + require.Equal(t, "a", v1) +} + +func TestV2(t *testing.T) { + run := func() (string, uint64, error) { + return "a", 2, nil + } + + v1, v2 := done.V2(run()) + require.Equal(t, "a", v1) + require.Equal(t, uint64(2), v2) +} + +func TestP0(t *testing.T) { + run := func() error { + return nil + } + + done.P0(run()) +} + +func TestP1(t *testing.T) { + run := func() (*string, error) { + v1 := "hello" + return &v1, nil + } + + p1 := done.P1(run()) + require.Equal(t, "hello", *p1) +} + +func TestP2(t *testing.T) { + run := func() (*int, *float64, error) { + v1 := 42 + v2 := 3.14 + return &v1, &v2, nil + } + + v1, v2 := done.P2(run()) + require.Equal(t, 42, *v1) + require.Equal(t, 3.14, *v2) +} + +func TestC0(t *testing.T) { + run := func() error { + return nil + } + + done.C0(run()) +} + +func TestC1(t *testing.T) { + run := func() (string, error) { + return "hello", nil + } + + v1 := done.C1(run()) + require.Equal(t, "hello", v1) +} + +func TestC2(t *testing.T) { + run := func() (int, float64, error) { + return 42, 3.14, nil + } + + v1, v2 := done.C2(run()) + require.Equal(t, 42, v1) + require.Equal(t, 3.14, v2) +}