Skip to content

Commit

Permalink
Merge pull request #219 from ecodeclub/dev
Browse files Browse the repository at this point in the history
准备 0.0.8
  • Loading branch information
flycash authored Sep 25, 2023
2 parents 71ad71d + 1966061 commit bcc3dea
Show file tree
Hide file tree
Showing 62 changed files with 6,919 additions and 701 deletions.
29 changes: 29 additions & 0 deletions .CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# 开发中

# v0.0.8
- [atomicx: 泛型封装 atomic.Value](https://github.com/gotomicro/ekit/pull/101)
- [queue: API 定义](https://github.com/gotomicro/ekit/pull/109)
- [queue: 基于堆和切片的优先级队列](https://github.com/gotomicro/ekit/pull/110)
Expand All @@ -7,6 +9,33 @@
- [queue: 基于切片的并发阻塞队列和基于 CAS 的并发队列设计](https://github.com/gotomicro/ekit/pull/119)
- [queue: 基于链表实现的有界/无界阻塞队列](https://github.com/gotomicro/ekit/pull/122)
- [queue: ConcurrentLinkBlockingQueue重命名为ConcurrentLinkedBlockingQueue](https://github.com/gotomicro/ekit/pull/123)
- [syncx: sync.Cond的超时等待版,Cond.WaitWithContext(ctx)](https://github.com/ecodeclub/ekit/pull/192)
- [copier: ReflectCopier copier支持类型转换](https://github.com/ecodeclub/ekit/issues/197)
- [mapx: TreeMap 添加 Keys 和 Values 方法](https://github.com/ecodeclub/ekit/pull/181)
- [mapx: 修正 HashMap 中使用泛型不当的地方](https://github.com/ecodeclub/ekit/pull/186)
- [mapx: 支持 builtinMap,用于接入其它装饰器实现](https://github.com/ecodeclub/ekit/pull/202)
- [pool: 重构TaskPool测试用例](https://github.com/ecodeclub/ekit/pull/178)
- [sqlx:ScanRows 和 ScanAll方法](https://github.com/ecodeclub/ekit/pull/180)
- [mapx: 修复红黑树删除节点问题](https://github.com/ecodeclub/ekit/pull/183)
- [sqlx: 构建Scanner抽象替代现有ScanRows及ScanAll](https://github.com/ecodeclub/ekit/pull/182)
- [sqlx: 预定义 Rows 接口](https://github.com/ecodeclub/ekit/pull/209)
- [pool: 重构TaskPool](https://github.com/ecodeclub/ekit/pull/184)
- [syncx:Map 支持 LoadOrStoreFunc 方法](https://github.com/ecodeclub/ekit/pull/194)
- [mapx: MutipleTreeMap](https://github.com/ecodeclub/ekit/pull/187)
- [mapx: 为 MultipleMap 添加 PutVals 方法](https://github.com/ecodeclub/ekit/pull/189)
- [mapx: LinkedMap 特性](https://github.com/ecodeclub/ekit/pull/191)
- [copier: ReflectCopier 支持忽略字段](https://github.com/ecodeclub/ekit/pull/196)
- [syncx: 重构LoadOrStoreFunc方法及相关测试](https://github.com/ecodeclub/ekit/pull/198)
- [slice: 添加Add函数,在指定位置插入元素](https://github.com/ecodeclub/ekit/pull/201)
- [slice: 优化delete方法,无需从头开始遍历](https://github.com/ecodeclub/ekit/pull/203)
- [slice: 重构 slice 中使用 equalFunc 的方法](https://github.com/ecodeclub/ekit/pull/205)
- [randx: 新增生成随机code方法](https://github.com/ecodeclub/ekit/pull/207)
- [slice: intersect方法优化, symmetricDiffSet重构](https://github.com/ecodeclub/ekit/pull/208)
- [sqlx: 修复EncryptColumn Scan方法string分支错误](https://github.com/ecodeclub/ekit/pull/211)
- [sqlx: Scanner 添加 NextResultSet 方法](https://github.com/ecodeclub/ekit/pull/212)
- [ekit: AnyValue 支持As[Type]类型 String 转换](https://github.com/ecodeclub/ekit/pull/213)
- [stringx: unsafe 转换 string 和 []byte](https://github.com/ecodeclub/ekit/pull/215)
- [stringx: 添加 Benchmark](https://github.com/ecodeclub/ekit/pull/216)

# v0.0.7
- [slice: FilterDelete](https://github.com/ecodeclub/ekit/pull/152)
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
# vendor/

.idea

.vscode
**/.DS_Store
Binary file added .imgs/contact_me_qr.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,13 @@
泛型工具库。

- [文档](https://ekit.gocn.vip/ekit/develop/guide/)

## 交流

交流群。原本我是觉得有一个群会削弱 github 的社区氛围,但是比较多人还是习惯于用群交流,所以我也搞了一个。

但是希望你进群之前要先想好,这个群并不希望大家讨论任何的社会议题,包括政治、历史、男女、情感等。我们希望这个群承担的功能是讨论技术问题和技术互助。

技术互助的意思是,你进群是希望有人来帮你解答问题;那么同样地,看到别人提问,也希望你能帮助解答。

![入群](./.imgs/contact_me_qr.jpg)
25 changes: 25 additions & 0 deletions bean/copier/converter/converter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2021 ecodeclub
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package converter

type Converter[Src any, Dst any] interface {
Convert(src Src) (Dst, error)
}

type ConverterFunc[Src any, Dst any] func(src Src) (Dst, error)

func (cf ConverterFunc[Src, Dst]) Convert(src Src) (Dst, error) {
return cf(src)
}
25 changes: 25 additions & 0 deletions bean/copier/converter/time2string.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2021 ecodeclub
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package converter

import "time"

type Time2String struct {
Pattern string
}

func (t Time2String) Convert(src time.Time) (string, error) {
return src.Format(t.Pattern), nil
}
68 changes: 66 additions & 2 deletions bean/copier/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,78 @@

package copier

import (
"github.com/ecodeclub/ekit/bean/copier/converter"
"github.com/ecodeclub/ekit/bean/option"
"github.com/ecodeclub/ekit/set"
)

// Copier 复制数据
// 1. 深拷贝亦或是浅拷贝,取决于具体的实现。每个实现都要声明清楚这一点;
// 2. Src 和 Dst 都必须是普通的结构体,支持组合
// 3. 只复制公共字段
// 这种设计设计,即使用 *Src 和 *Dst 可能加剧内存逃逸
type Copier[Src any, Dst any] interface {
// CopyTo 将 src 中的数据复制到 dst 中
CopyTo(src *Src, dst *Dst) error
CopyTo(src *Src, dst *Dst, opts ...option.Option[options]) error
// Copy 将创建一个 Dst 的实例,并且将 Src 中的数据复制过去
Copy(src *Src) (*Dst, error)
Copy(src *Src, opts ...option.Option[options]) (*Dst, error)
}

// options 执行复制操作时的可选配置
type options struct {
// ignoreFields 执行复制操作时,需要忽略的字段
ignoreFields *set.MapSet[string]
// convertFields 执行转换的field和转化接口的泛型包装
convertFields map[string]converterWrapper
}

type converterWrapper func(src any) (any, error)

func newOptions() options {
return options{}
}

// InIgnoreFields 判断 str 是不是在 ignoreFields 里面
func (r *options) InIgnoreFields(str string) bool {
// 如果没有设置过忽略的字段的话,ignoreFields 就有可能是 nil,这里需要判断一下
if r.ignoreFields == nil {
return false
}
return r.ignoreFields.Exist(str)
}

// IgnoreFields 设置复制时要忽略的字段(option 设计模式)
func IgnoreFields(fields ...string) option.Option[options] {
return func(opt *options) {
if len(fields) < 1 {
return
}
// 需要用的时候再延迟初始化 ignoreFields
if opt.ignoreFields == nil {
opt.ignoreFields = set.NewMapSet[string](len(fields))
}
for i := 0; i < len(fields); i++ {
opt.ignoreFields.Add(fields[i])
}
}
}

func ConvertField[Src any, Dst any](field string, converter converter.Converter[Src, Dst]) option.Option[options] {
return func(opt *options) {
if field == "" || converter == nil {
return
}
if opt.convertFields == nil {
opt.convertFields = make(map[string]converterWrapper, 8)
}
opt.convertFields[field] = func(src any) (any, error) {
var dst Dst
srcVal, ok := src.(Src)
if !ok {
return dst, errConvertFieldTypeNotMatch
}
return converter.Convert(srcVal)
}
}
}
5 changes: 5 additions & 0 deletions bean/copier/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,15 @@
package copier

import (
"errors"
"fmt"
"reflect"
)

var (
errConvertFieldTypeNotMatch = errors.New("ekit: 转化字段类型不匹配")
)

// newErrTypeError copier 不支持的类型
func newErrTypeError(typ reflect.Type) error {
return fmt.Errorf("ekit: copier 入口只支持 Struct 不支持类型 %v, 种类 %v", typ, typ.Kind())
Expand Down
Loading

0 comments on commit bcc3dea

Please sign in to comment.