csv

package module
v1.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 6, 2024 License: MIT Imports: 8 Imported by: 1

README

csv

parse csv data to object(struct,protobuf,map[K]V,slice[E])

读取csv数据,转换成对象(struct,protobuf,map[K]V,slice[E]等),支持自定义解析接口,以及结构嵌套(支持2层)

示例

// 模拟一个物品配置结构
type ItemCfg struct {
  CfgId  int32  `json:"CfgId,omitempty"`  // 配置id
  Name   string `json:"Name,omitempty"`   // 物品名
  Detail string `json:"Detail,omitempty"` // 物品描述
  Unique bool   `json:"Unique,omitempty"` // 是否是不可叠加的物品
}

csv数据转换成map

rows := [][]string{
    {"CfgId", "Name", "Detail", "Unique", "unknownColumnTest"},
    {"1", "普通物品1", "普通物品1详细信息", "false", "123"},
    {"2", "普通物品2", "普通物品2详细信息", "false", "test"},
    {"3", "装备3", "装备3详细信息", "true", ""},
}
m := make(map[int32]*ItemCfg)
err := ReadCsvFromDataMap(rows, m, nil)

csv数据转换成slice

rows := [][]string{
    {"CfgId", "Name", "Detail", "Unique", "unknownColumnTest"},
    {"1", "普通物品1", "普通物品1详细信息", "false", "123"},
    {"2", "普通物品2", "普通物品2详细信息", "false", "test"},
    {"3", "装备3", "装备3详细信息", "true", ""},
}
s := make([]*ItemCfg, 0)
s,_ = ReadCsvFromDataSlice(rows, s, nil)

key-value格式的csv数据转换成对象

type Settings struct {
  ImageQuality int
  Volume       int
  Language     string
}
rows := [][]string{
  {"Key", "Value", "comment"},
  {"ImageQuality", "100", "画质设置"},
  {"Volume", "80", "音量设置"},
  {"Language", "Simplified Chinese", "语言设置"},
}
settings := new(Settings)
err := ReadCsvFromDataObject(rows, settings, nil)

自定义解析接口

rows := [][]string{
    {"CfgId", "Color", "ColorFlags"},
    {"1", "Red", "Red;Green;Blue"},
    {"2", "Gray", "Gray;Yellow"},
    {"3", "", ""},
}
type colorCfg struct {
    CfgId      int32
    Color      Color // Color是protobuf定义的枚举
    ColorFlags int32 // 颜色的组合值,如 Red | Green
}
option := DefaultCsvOption
// 注册颜色枚举的自定义解析接口,csv中可以直接填写颜色对应的字符串
option.RegisterConverterByType(reflect.TypeOf(Color(0)), func(obj any, columnName, fieldStr string) any {
    if colorValue, ok := Color_value["Color_"+fieldStr]; ok {
        return Color(colorValue)
    }
    return Color(0)
})
// 注册列名对应的解析接口
// 这里的ColorFlags列演示了一种特殊需求: 颜色的组合值用更易读的方式在csv中填写
option.RegisterConverterByColumnName("ColorFlags", func(obj any, columnName, fieldStr string) any {
    colorStrSlice := strings.Split(fieldStr, ";")
    flags := int32(0)
    for _, colorStr := range colorStrSlice {
        if colorValue, ok := Color_value["Color_"+colorStr]; ok && colorValue > 0 {
            flags |= 1 << (colorValue - 1)
        }
    }
    return flags
})
m := make(map[int]*colorCfg)
err := ReadCsvFromDataMap(rows, m, &option)

嵌套结构

详见csv_test.go里的TestNestStruct用例

更多示例

游戏项目中经常使用csv作为配置文件,并需要支持热更新(服务器不重启的情况下,重新加载配置数据)

可参考gserver中的配置数据的使用方式(https://github.com/fish-tennis/gserver/tree/main/cfg)

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultOption = CsvOption{
	ColumnNameRowIndex: 0,
	DataBeginRowIndex:  1,
	SliceSeparator:     ";",
	KvSeparator:        "_",
	PairSeparator:      "#",
}

默认csv设置

Functions

func Atoi

func Atoi(s string) int

func Atoi64

func Atoi64(s string) int64

func Atou

func Atou(s string) uint64

func ConvertCsvLineToValue

func ConvertCsvLineToValue(valueType reflect.Type, row []string, columnNames []string, option *CsvOption) reflect.Value

func ConvertStringToFieldValue

func ConvertStringToFieldValue(object, fieldVal reflect.Value, columnName, fieldString string, option *CsvOption, isSubStruct bool)

字段赋值,根据字段的类型,把字符串转换成对应的值

func ConvertStringToRealType

func ConvertStringToRealType(typ reflect.Type, s string) any

支持int,float,string,[]byte,complex,bool

func ParseNestStringSlice

func ParseNestStringSlice(cellString string, option *CsvOption, nestFieldNames ...string) [][]*StringPair

Name_a#Items_{CfgId_1#Num_1;CfgId_2#Num_1};Name_b#Items_{CfgId_1#Num_2;CfgId_2#Num_2}

func ReadCsvFile

func ReadCsvFile(file string) ([][]string, error)

func ReadCsvFileMap

func ReadCsvFileMap[M ~map[K]V, K IntOrString, V any](file string, m M, option *CsvOption) error

csv数据转换成map V支持proto.Message和普通struct结构

func ReadCsvFileObject

func ReadCsvFileObject[V any](file string, v V, option *CsvOption) error

key-value格式的csv数据给对象赋值 V支持proto.Message和普通struct结构

func ReadCsvFileSlice

func ReadCsvFileSlice[Slice ~[]V, V any](file string, s Slice, option *CsvOption) (Slice, error)

csv数据转换成slice V支持proto.Message和普通struct结构

func ReadCsvFromDataMap

func ReadCsvFromDataMap[M ~map[K]V, K IntOrString, V any](rows [][]string, m M, option *CsvOption) error

csv数据转换成map V支持proto.Message和普通struct结构

func ReadCsvFromDataObject

func ReadCsvFromDataObject[V any](rows [][]string, v V, option *CsvOption) error

key-value格式的csv数据转换成对象 V支持proto.Message和普通struct结构

func ReadCsvFromDataSlice

func ReadCsvFromDataSlice[Slice ~[]V, V any](rows [][]string, s Slice, option *CsvOption) (Slice, error)

csv数据转换成slice V支持proto.Message和普通struct结构

Types

type CsvOption

type CsvOption struct {
	// 数据行索引(>=1)
	DataBeginRowIndex int

	// 字段名数据行索引(>=0)
	ColumnNameRowIndex int

	// key-value格式的csv数据给对象赋值,数据行索引(>=0)
	ObjectDataBeginRowIndex int

	// 是否禁用protobuf的字段别名(struct tag里的name),默认不禁用
	//  proto2示例 Num *int32 `protobuf:"varint,1,opt,name=num"`
	//  proto3示例 Num int32  `protobuf:"varint,1,opt,name=num,proto3"`
	DisableProtobufAliasName bool

	// 是否禁用json的字段别名(struct tag里的name),默认不禁用
	//  示例 Num *int32 `json:"num,omitempty"`
	DisableJsonAliasName bool

	// 数组分隔符
	// 如数组分隔符为;时,则1;2;3可以表示[1,2,3]的数组
	SliceSeparator string

	// Key-Value分隔符
	// 如KvSeparator为_ PairSeparator为#
	// 则a_1#b_2#c_3可以表示{"a":1,"b":2,"c":3}的map或者如下结构体
	// type S struct {
	//   a string
	//   b string
	//   c int
	// }
	KvSeparator string

	// 不同Key-Value之间的分隔符
	// 如KvSeparator为_ PairSeparator为#
	// 则a_1#b_2#c_3可以表示{"a":1,"b":2,"c":3}的map或者如下结构体
	// type S struct {
	//   a string
	//   b string
	//   c int
	// }
	PairSeparator string
	// contains filtered or unexported fields
}

func (*CsvOption) GetConverterByColumnName

func (co *CsvOption) GetConverterByColumnName(columnName string) FieldConverter

func (*CsvOption) GetConverterByType

func (co *CsvOption) GetConverterByType(typ reflect.Type) FieldConverter

func (*CsvOption) GetConverterByTypePtrOrStruct

func (co *CsvOption) GetConverterByTypePtrOrStruct(typ reflect.Type) (converter FieldConverter, convertToElem bool)

如果typ是Struct,但是注册的FieldConverter是同类型的Ptr,则会返回Ptr类型的FieldConverter,同时convertToElem返回true

func (*CsvOption) RegisterConverterByColumnName

func (co *CsvOption) RegisterConverterByColumnName(columnName string, converter FieldConverter) *CsvOption

注册列名对应的转换接口

func (*CsvOption) RegisterConverterByType

func (co *CsvOption) RegisterConverterByType(typ reflect.Type, converter FieldConverter) *CsvOption

注册类型对应的转换接口

type FieldConverter

type FieldConverter func(obj any, columnName, fieldStr string) any

字段转换接口

type IntOrString

type IntOrString interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~string
}

type StringPair

type StringPair struct {
	Key   string
	Value string
}

func ParseNestString

func ParseNestString(cellString string, option *CsvOption, nestFieldNames ...string) []*StringPair

解析有嵌套结构的字符串 如 CfgId_1#ConsumeItems_{CfgId_1#Num_2;CfgId_2#Num_3}#Rewards_{CfgId_1#Num_1}#CountLimit_2 解析成 [{CfgId,1},{ConsumeItems,CfgId_1#Num_2;CfgId_2#Num_3},{Rewards,CfgId_1#Num_1},{CountLimit,2}]

func ParsePairString

func ParsePairString(cellString string, option *CsvOption) []*StringPair

把K1_V1#K2_V2#K3_V3转换成StringPair数组(如[{K1,V1},{K2,V2},{K3,V3}]

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL