From 91f9acefe109ab7f45892e0a43e9f39476968f86 Mon Sep 17 00:00:00 2001 From: davyxu Date: Fri, 31 Jul 2020 13:50:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=95=B0=E7=BB=84=E5=88=97?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E9=97=AE=E9=A2=98=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 2 +- v3/checker/checker_data.go | 29 ++++++-- v3/checker/checker_enumvalue.go | 21 +++--- v3/checker/entry.go | 49 ++++++++++++- v3/compiler/flow.go | 3 +- v3/compiler/merge.go | 24 +++---- v3/example/csharp/TabtoyExample/table_gen.cs | 52 +++++++++++++- v3/example/csv/Data.csv | 17 ++++- v3/example/csv/Data2.csv | 28 ++++---- v3/example/csv/Extend.csv | 14 ++++ v3/example/csv/Index.csv | 1 + v3/example/csv/Run.sh | 6 ++ v3/example/csv/Type.csv | 29 ++++---- v3/example/golang/table_gen.go | 22 ++++-- v3/example/java/cfg/table_gen.json | 14 ++-- v3/example/java/src/main/java/main/Table.java | 10 ++- v3/example/json/table_gen.json | 14 ++-- v3/example/jsontype/type_gen.json | 57 +++++++-------- v3/example/lua/table_gen.lua | 16 +++-- v3/example/xlsx/Data.xlsx | Bin 9310 -> 9359 bytes v3/example/xlsx/Data2.xlsx | Bin 9216 -> 9122 bytes v3/example/xlsx/Index.xlsx | Bin 9150 -> 9208 bytes v3/example/xlsx/KV.xlsx | Bin 9209 -> 9282 bytes v3/example/xlsx/Run.sh | 5 ++ v3/example/xlsx/Type.xlsx | Bin 9817 -> 10028 bytes v3/gen/bindata/struct.go | 3 +- v3/gen/jsondata/func.go | 17 +++-- v3/gen/jsondata2/gen.go | 23 +++--- v3/gen/luasrc/func.go | 23 +++--- v3/model/cell.go | 18 +++-- v3/model/datatab.go | 20 +----- v3/report/errid.go | 29 ++++---- v3/tests/data_test.go | 67 ++++++++++++++---- v3/tests/emulator.go | 2 +- v3/tests/type_test.go | 33 +++++++++ 35 files changed, 449 insertions(+), 199 deletions(-) create mode 100644 v3/example/csv/Extend.csv diff --git a/main.go b/main.go index 6bb84457..2847b994 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,7 @@ import ( var log = golog.New("main") const ( - Version = "3.0.0" + Version = "3.0.1" ) var enableProfile = false diff --git a/v3/checker/checker_data.go b/v3/checker/checker_data.go index 8b0d6648..5d43db59 100644 --- a/v3/checker/checker_data.go +++ b/v3/checker/checker_data.go @@ -4,7 +4,6 @@ import ( "github.com/davyxu/tabtoy/v3/model" "github.com/davyxu/tabtoy/v3/report" "strconv" - "strings" ) // 检查数据与定义类型是否匹配 @@ -35,12 +34,9 @@ func checkDataType(globals *model.Globals) { crrCell = inputCell currHeader = header - if inputCell.Value == "" { - continue - } - if header.TypeInfo.IsArray() { - for _, value := range strings.Split(inputCell.Value, header.TypeInfo.ArraySplitter) { + for _, value := range inputCell.ValueList { + err := checkSingleValue(header, value) if err != nil { report.ReportError("DataMissMatchTypeDefine", currHeader.TypeInfo.FieldType, crrCell.String()) @@ -61,31 +57,49 @@ func checkDataType(globals *model.Globals) { func checkSingleValue(header *model.HeaderField, value string) error { switch model.LanguagePrimitive(header.TypeInfo.FieldType, "go") { case "int16": + if value == "" { + return nil + } _, err := strconv.ParseInt(value, 10, 16) if err != nil { return err } case "int32": + if value == "" { + return nil + } _, err := strconv.ParseInt(value, 10, 32) if err != nil { return err } case "int64": + if value == "" { + return nil + } _, err := strconv.ParseInt(value, 10, 64) if err != nil { return err } case "uint16": + if value == "" { + return nil + } _, err := strconv.ParseUint(value, 10, 16) if err != nil { return err } case "uint32": + if value == "" { + return nil + } _, err := strconv.ParseUint(value, 10, 32) if err != nil { return err } case "uint64": + if value == "" { + return nil + } _, err := strconv.ParseUint(value, 10, 64) if err != nil { return err @@ -96,6 +110,9 @@ func checkSingleValue(header *model.HeaderField, value string) error { return err } case "float64": + if value == "" { + return nil + } _, err := strconv.ParseFloat(value, 64) if err != nil { return err diff --git a/v3/checker/checker_enumvalue.go b/v3/checker/checker_enumvalue.go index e588a0b2..3707a73e 100644 --- a/v3/checker/checker_enumvalue.go +++ b/v3/checker/checker_enumvalue.go @@ -3,7 +3,6 @@ package checker import ( "github.com/davyxu/tabtoy/v3/model" "github.com/davyxu/tabtoy/v3/report" - "strings" ) // 枚举值的解析是放在输出端处理的, 例如json中, 所以在这里提前检查 @@ -32,17 +31,14 @@ func checkEnumValue(globals *model.Globals) { continue } - if inputCell.Value != "" { + if header.TypeInfo.IsArray() { - if header.TypeInfo.IsArray() { - - for _, v := range strings.Split(inputCell.Value, header.TypeInfo.ArraySplitter) { - checkEnumFieldValue(globals, header, v, inputCell) - } - - } else { - checkEnumFieldValue(globals, header, inputCell.Value, inputCell) + for _, v := range inputCell.ValueList { + checkEnumFieldValue(globals, header, v, inputCell) } + + } else { + checkEnumFieldValue(globals, header, inputCell.Value, inputCell) } } @@ -52,6 +48,11 @@ func checkEnumValue(globals *model.Globals) { // 检查枚举值是否存在有效 func checkEnumFieldValue(globals *model.Globals, header *model.HeaderField, value string, inputCell *model.Cell) { + + if inputCell.Value == "" { + return + } + enumValue := globals.Types.GetEnumValue(header.TypeInfo.FieldType, value) if enumValue == nil { report.ReportError("UnknownEnumValue", header.TypeInfo.FieldType, inputCell.String()) diff --git a/v3/checker/entry.go b/v3/checker/entry.go index 9388cbec..f9392ed5 100644 --- a/v3/checker/entry.go +++ b/v3/checker/entry.go @@ -1,8 +1,53 @@ package checker -import "github.com/davyxu/tabtoy/v3/model" +import ( + "github.com/davyxu/tabtoy/v3/model" + "github.com/davyxu/tabtoy/v3/report" +) -func CheckData(globals *model.Globals) { +func PreCheck(dataList *model.DataTableList) { + + type ArrayFieldDefine struct { + FieldName string + ObjectName string + } + + fieldCountByField := map[ArrayFieldDefine]int{} + + // 合并前的数据表 + for _, tab := range dataList.AllTables() { + + // 遍历输入数据的每一列 + for _, header := range tab.Headers { + + // 输入的列头,为空表示改列被注释 + if header.TypeInfo == nil { + continue + } + + fieldKey := ArrayFieldDefine{ + FieldName: header.TypeInfo.FieldName, + ObjectName: header.TypeInfo.Name, + } + + if header.TypeInfo.IsArray() { + arrayFieldCount := tab.ArrayFieldCount(header) + if preFieldCount, ok := fieldCountByField[fieldKey]; ok { + + if preFieldCount != arrayFieldCount { + report.ReportError("ArrayMultiColumnDefineNotMatch") + } + } else { + fieldCountByField[fieldKey] = arrayFieldCount + } + } + + } + } +} + +// merge后检查 +func PostCheck(globals *model.Globals) { checkEnumValue(globals) checkRepeat(globals) diff --git a/v3/compiler/flow.go b/v3/compiler/flow.go index 87a1e63e..812d77c6 100644 --- a/v3/compiler/flow.go +++ b/v3/compiler/flow.go @@ -57,6 +57,7 @@ func Compile(globals *model.Globals) (ret error) { report.Log.Debugln("Checking types...") checker.CheckType(globals.Types) + checker.PreCheck(&dataList) if kvList.Count() > 0 { report.Log.Debugln("Merge key-value tables...") @@ -77,7 +78,7 @@ func Compile(globals *model.Globals) (ret error) { // 合并所有的数据表 MergeData(&dataList, &globals.Datas, globals.Types) - checker.CheckData(globals) + checker.PostCheck(globals) return nil } diff --git a/v3/compiler/merge.go b/v3/compiler/merge.go index a0fd9ecb..fff9ee64 100644 --- a/v3/compiler/merge.go +++ b/v3/compiler/merge.go @@ -3,6 +3,7 @@ package compiler import ( "github.com/davyxu/tabtoy/v3/model" "github.com/davyxu/tabtoy/v3/report" + "strings" ) func createOutputTable(symbols *model.TypeTable, inputTab *model.DataTable) *model.DataTable { @@ -114,23 +115,20 @@ func MergeData(inputList, outputList *model.DataTableList, symbols *model.TypeTa func combineRepeatedCell(outputCell, inputCell *model.Cell, inputHeader *model.HeaderField, inputTab *model.DataTable) { - spliter := inputHeader.TypeInfo.ArraySplitter + // 数组列, 单列情况 + if inputTab.ArrayFieldCount(inputHeader) == 1 { - if inputTab.RepeatedFieldIndex(inputHeader) > 0 { - - if outputCell.Value != "" || model.LanguagePrimitive(inputHeader.TypeInfo.FieldType, "go") == "string" { - outputCell.Value += spliter + // 不为空时, 切割值为数组 + if inputCell.Value != "" { + for _, element := range strings.Split(inputCell.Value, inputHeader.TypeInfo.ArraySplitter) { + outputCell.ValueList = append(outputCell.ValueList, element) + } } - } - var inputValue string - if inputCell.Value == "" { - inputValue = model.FetchDefaultValue(inputHeader.TypeInfo.FieldType) } else { - inputValue = inputCell.Value - } - // 将多个列中的数值合并到最终单元格的值中, Spliter分割, 分割过程在每种数据gen中处理 - outputCell.Value += inputValue + // 数组列, 多列情况, 每列添加到单元格 + outputCell.ValueList = append(outputCell.ValueList, inputCell.Value) + } } diff --git a/v3/example/csharp/TabtoyExample/table_gen.cs b/v3/example/csharp/TabtoyExample/table_gen.cs index c7a3f8f7..65dda9a4 100644 --- a/v3/example/csharp/TabtoyExample/table_gen.cs +++ b/v3/example/csharp/TabtoyExample/table_gen.cs @@ -1,6 +1,6 @@ // Generated by github.com/davyxu/tabtoy // DO NOT EDIT!! -// Version: 3.0.1 +// Version: 3.0.0 using System; using System.Collections.Generic; @@ -22,6 +22,8 @@ public partial class ExampleData : tabtoy.ITableSerializable public float Rate = 0; public ActorType Type = ActorType.None; public List Skill = new List(); + public Int32 Buff = 0; + public List TagList = new List(); public List Multi = new List(); #region Deserialize Code @@ -57,7 +59,17 @@ public void Deserialize( tabtoy.TableReader reader ) reader.ReadInt32( ref Skill ); } break; - case 0x660005: + case 0x20005: + { + reader.ReadInt32( ref Buff ); + } + break; + case 0x6c0006: + { + reader.ReadString( ref TagList ); + } + break; + case 0x660007: { reader.ReadInt32( ref Multi ); } @@ -73,6 +85,34 @@ public void Deserialize( tabtoy.TableReader reader ) #endregion } + public partial class ExtendData : tabtoy.ITableSerializable + { + public float Additive = 0; + + #region Deserialize Code + public void Deserialize( tabtoy.TableReader reader ) + { + UInt32 mamaSaidTagNameShouldBeLong = 0; + while ( reader.ReadTag(ref mamaSaidTagNameShouldBeLong) ) + { + switch (mamaSaidTagNameShouldBeLong) + { + case 0x70000: + { + reader.ReadFloat( ref Additive ); + } + break; + default: + { + reader.SkipFiled(mamaSaidTagNameShouldBeLong); + } + break; + } + } + } + #endregion + } + public partial class ExampleKV : tabtoy.ITableSerializable { public string ServerIP = string.Empty; @@ -119,6 +159,8 @@ public partial class Table { // table: ExampleData public List ExampleData = new List(); + // table: ExtendData + public List ExtendData = new List(); // table: ExampleKV public List ExampleKV = new List(); @@ -135,6 +177,7 @@ public ExampleKV GetKeyValue_ExampleKV() public void ResetData( ) { ExampleData.Clear(); + ExtendData.Clear(); ExampleKV.Clear(); ExampleDataByID.Clear(); } @@ -157,6 +200,11 @@ public void Deserialize( tabtoy.TableReader reader ) reader.ReadStruct(ref ExampleData); } break; + case "ExtendData": + { + reader.ReadStruct(ref ExtendData); + } + break; case "ExampleKV": { reader.ReadStruct(ref ExampleKV); diff --git a/v3/example/csv/Data.csv b/v3/example/csv/Data.csv index 385fdeea..47727ff9 100644 --- a/v3/example/csv/Data.csv +++ b/v3/example/csv/Data.csv @@ -1,3 +1,14 @@ -ID,,,б,,б,б,, -100,,3.14,3,,1,2,1|2,3 -200,Ŭ˹,1.2,100,Genji,,90,4, +ID,,,б,,б,б,,,, +100,,3.14,3,,1,2,100,a|b,1,3 +200,Ŭ˹,1.2,100,,,90,1,c,4, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, diff --git a/v3/example/csv/Data2.csv b/v3/example/csv/Data2.csv index 84025595..be7bbb75 100644 --- a/v3/example/csv/Data2.csv +++ b/v3/example/csv/Data2.csv @@ -1,14 +1,14 @@ -ID,,,,б -300,,79.4,Դ, -400,߶,0.63,ʹ, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, -,,,, +ID,,, +300,,79.4,Դ +400,߶,0.63,ʹ +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, +,,, diff --git a/v3/example/csv/Extend.csv b/v3/example/csv/Extend.csv new file mode 100644 index 00000000..2a472f95 --- /dev/null +++ b/v3/example/csv/Extend.csv @@ -0,0 +1,14 @@ + +1.1 +1.2 + + + + + + + + + + + diff --git a/v3/example/csv/Index.csv b/v3/example/csv/Index.csv index a8fa5aa4..efdfda5c 100644 --- a/v3/example/csv/Index.csv +++ b/v3/example/csv/Index.csv @@ -4,3 +4,4 @@ ֵ,ExampleKV,KV2.csv,n ݱ,ExampleData,Data.csv, ݱ,ExampleData,Data2.csv, +ݱ,ExtendData,Extend.csv, diff --git a/v3/example/csv/Run.sh b/v3/example/csv/Run.sh index 444afd0c..42e3c414 100644 --- a/v3/example/csv/Run.sh +++ b/v3/example/csv/Run.sh @@ -16,6 +16,12 @@ go build -v -o ./tabtoy github.com/davyxu/tabtoy -java_out=../java/src/main/java/main/Table.java \ -package=main + +if [[ $? -ne 0 ]] ; then + read -rsp $'Errors occurred...\n' ; + exit 1 +fi + cp ../json/table_gen.json ../java/cfg rm -f tabtoy \ No newline at end of file diff --git a/v3/example/csv/Type.csv b/v3/example/csv/Type.csv index ed5afb2f..1c4d9b0c 100644 --- a/v3/example/csv/Type.csv +++ b/v3/example/csv/Type.csv @@ -1,12 +1,17 @@ -,,ʶ,ֶ,ֶ,и,ֵ,, -ͷ,ExampleData,ID,ID,int,,,, -ͷ,ExampleData,,Name,string,,,,a|b -ͷ,ExampleData,,Rate,float,,,,c -ͷ,ExampleData,,Type,ActorType,,,, -ͷ,ExampleData,б,Skill,int,|,,, -ͷ,ExampleData,,Multi,int,|,,, -ö,ActorType,,None,int,,0,, -ö,ActorType,,Pharah,int,,1,,k|n -ö,ActorType,,Junkrat,int,,2,,e -ö,ActorType,Դ,Genji,int,,3,, -ö,ActorType,ʹ,Mercy,int,,4,, +,,ʶ,ֶ,ֶ,и,ֵ,,,, +ͷ,ExampleData,ID,ID,int,,,,,, +ͷ,ExampleData,,Name,string,,,,,, +ͷ,ExampleData,,Rate,float,,,,,, +ͷ,ExampleData,,Type,ActorType,,,,,, +ͷ,ExampleData,б,Skill,int,|,,,,, +ͷ,ExampleData,,Buff,int,,,,ֶڲԶ,, +ͷ,ExampleData,,TagList,string,|,,,,, +ͷ,ExampleData,,Multi,int,|,,,,, +ö,ActorType,,None,int,,0,,,, +ö,ActorType,,Pharah,int,,1,,,, +ö,ActorType,,Junkrat,int,,2,,,, +ö,ActorType,Դ,Genji,int,,3,,,, +ö,ActorType,ʹ,Mercy,int,,4,,,, +ͷ,ExtendData,,Additive,float,,,,ֶڲԶ,, +,,,,,,,,,, +,,,,,,,,,, diff --git a/v3/example/golang/table_gen.go b/v3/example/golang/table_gen.go index 4e8edd54..2d77b95b 100644 --- a/v3/example/golang/table_gen.go +++ b/v3/example/golang/table_gen.go @@ -1,6 +1,6 @@ // Generated by github.com/davyxu/tabtoy // DO NOT EDIT!! -// Version: 3.0.1 +// Version: 3.0.0 package main type TableEnumValue struct { @@ -36,12 +36,18 @@ func (self ActorType) String() string { } type ExampleData struct { - ID int32 `tb_name:"任务ID"` - Name string `tb_name:"名称"` - Rate float32 `tb_name:"比例"` - Type ActorType `tb_name:"类型"` - Skill []int32 `tb_name:"技能列表"` - Multi []int32 `tb_name:"多列"` + ID int32 `tb_name:"任务ID"` + Name string `tb_name:"名称"` + Rate float32 `tb_name:"比例"` + Type ActorType `tb_name:"类型"` + Skill []int32 `tb_name:"技能列表"` + Buff int32 `tb_name:"增益"` + TagList []string `tb_name:"标记"` + Multi []int32 `tb_name:"多列"` +} + +type ExtendData struct { + Additive float32 `tb_name:"附加"` } type ExampleKV struct { @@ -53,6 +59,7 @@ type ExampleKV struct { // Combine struct type Table struct { ExampleData []*ExampleData // table: ExampleData + ExtendData []*ExtendData // table: ExtendData ExampleKV []*ExampleKV // table: ExampleKV // Indices @@ -98,6 +105,7 @@ func (self *Table) ResetData() error { } self.ExampleData = self.ExampleData[0:0] + self.ExtendData = self.ExtendData[0:0] self.ExampleKV = self.ExampleKV[0:0] self.ExampleDataByID = map[int32]*ExampleData{} diff --git a/v3/example/java/cfg/table_gen.json b/v3/example/java/cfg/table_gen.json index 55d244bf..438d14e9 100644 --- a/v3/example/java/cfg/table_gen.json +++ b/v3/example/java/cfg/table_gen.json @@ -1,11 +1,15 @@ { "@Tool": "github.com/davyxu/tabtoy", - "@Version": "3.0.1", + "@Version": "3.0.0", "ExampleData":[ - { "ID": 100, "Name": "扎克镇", "Rate": 3.14, "Type": 2, "Skill": [3,1,2], "Multi": [1,2,3] }, - { "ID": 200, "Name": "阿努比斯神庙", "Rate": 1.2, "Type": 3, "Skill": [100,0,90], "Multi": [4,0] }, - { "ID": 300, "Name": "花村", "Rate": 79.4, "Type": 3, "Skill": [0], "Multi": [] }, - { "ID": 400, "Name": "艾兴瓦尔德", "Rate": 0.63, "Type": 4, "Skill": [0], "Multi": [] } + { "ID": 100, "Name": "扎克镇", "Rate": 3.14, "Type": 2, "Skill": [3,1,2], "Buff": 100, "TagList": ["a","b"], "Multi": [1,3] }, + { "ID": 200, "Name": "阿努比斯神庙", "Rate": 1.2, "Type": 1, "Skill": [100,0,90], "Buff": 1, "TagList": ["c"], "Multi": [4,0] }, + { "ID": 300, "Name": "花村", "Rate": 79.4, "Type": 3, "Skill": [], "Buff": 0, "TagList": [], "Multi": [] }, + { "ID": 400, "Name": "艾兴瓦尔德", "Rate": 0.63, "Type": 4, "Skill": [], "Buff": 0, "TagList": [], "Multi": [] } + ], + "ExtendData":[ + { "Additive": 1.1 }, + { "Additive": 1.2 } ], "ExampleKV":[ { "ServerIP": "8.8.8.8", "ServerPort": 1024, "GroupID": [10,20] } diff --git a/v3/example/java/src/main/java/main/Table.java b/v3/example/java/src/main/java/main/Table.java index 172b5a79..8971a138 100644 --- a/v3/example/java/src/main/java/main/Table.java +++ b/v3/example/java/src/main/java/main/Table.java @@ -1,6 +1,6 @@ // Generated by github.com/davyxu/tabtoy // DO NOT EDIT!! -// Version: 3.0.1 +// Version: 3.0.0 package main; import java.util.ArrayList; import java.util.HashMap; @@ -50,9 +50,15 @@ public class ExampleData { public float Rate = 0; // 比例; public ActorType Type = ActorType.None; // 类型; public int[] Skill = new int[]{}; // 技能列表; + public int Buff = 0; // 增益; + public String[] TagList = new String[]{}; // 标记; public int[] Multi = new int[]{}; // 多列; } + public class ExtendData { + public float Additive = 0; // 附加; + } + public class ExampleKV { public String ServerIP = ""; // 服务器IP; public int ServerPort = 0; // 服务器端口; @@ -61,6 +67,7 @@ public class ExampleKV { public List ExampleData = new ArrayList<>(); // table: ExampleData + public List ExtendData = new ArrayList<>(); // table: ExtendData public List ExampleKV = new ArrayList<>(); // table: ExampleKV // Indices @@ -91,6 +98,7 @@ public void ResetData() { } ExampleData.clear(); + ExtendData.clear(); ExampleKV.clear(); ExampleDataByID.clear(); diff --git a/v3/example/json/table_gen.json b/v3/example/json/table_gen.json index 55d244bf..438d14e9 100644 --- a/v3/example/json/table_gen.json +++ b/v3/example/json/table_gen.json @@ -1,11 +1,15 @@ { "@Tool": "github.com/davyxu/tabtoy", - "@Version": "3.0.1", + "@Version": "3.0.0", "ExampleData":[ - { "ID": 100, "Name": "扎克镇", "Rate": 3.14, "Type": 2, "Skill": [3,1,2], "Multi": [1,2,3] }, - { "ID": 200, "Name": "阿努比斯神庙", "Rate": 1.2, "Type": 3, "Skill": [100,0,90], "Multi": [4,0] }, - { "ID": 300, "Name": "花村", "Rate": 79.4, "Type": 3, "Skill": [0], "Multi": [] }, - { "ID": 400, "Name": "艾兴瓦尔德", "Rate": 0.63, "Type": 4, "Skill": [0], "Multi": [] } + { "ID": 100, "Name": "扎克镇", "Rate": 3.14, "Type": 2, "Skill": [3,1,2], "Buff": 100, "TagList": ["a","b"], "Multi": [1,3] }, + { "ID": 200, "Name": "阿努比斯神庙", "Rate": 1.2, "Type": 1, "Skill": [100,0,90], "Buff": 1, "TagList": ["c"], "Multi": [4,0] }, + { "ID": 300, "Name": "花村", "Rate": 79.4, "Type": 3, "Skill": [], "Buff": 0, "TagList": [], "Multi": [] }, + { "ID": 400, "Name": "艾兴瓦尔德", "Rate": 0.63, "Type": 4, "Skill": [], "Buff": 0, "TagList": [], "Multi": [] } + ], + "ExtendData":[ + { "Additive": 1.1 }, + { "Additive": 1.2 } ], "ExampleKV":[ { "ServerIP": "8.8.8.8", "ServerPort": 1024, "GroupID": [10,20] } diff --git a/v3/example/jsontype/type_gen.json b/v3/example/jsontype/type_gen.json index e2933ca8..57e243d1 100644 --- a/v3/example/jsontype/type_gen.json +++ b/v3/example/jsontype/type_gen.json @@ -1,6 +1,6 @@ { "@Tool": "github.com/davyxu/tabtoy", - "@Version": "3.0.1", + "@Version": "3.0.0", "Objects": [ { "Name": "ActorType", @@ -16,20 +16,13 @@ "Name": "Pharah", "Type": "int", "Comment": "法鸡", - "Value": "1", - "Tags": [ - "k", - "n" - ] + "Value": "1" }, { "Name": "Junkrat", "Type": "int", "Comment": "狂鼠", - "Value": "2", - "Tags": [ - "e" - ] + "Value": "2" }, { "Name": "Genji", @@ -58,19 +51,12 @@ { "Name": "Name", "Type": "string", - "Comment": "名称", - "Tags": [ - "a", - "b" - ] + "Comment": "名称" }, { "Name": "Rate", "Type": "float", - "Comment": "比例", - "Tags": [ - "c" - ] + "Comment": "比例" }, { "Name": "Type", @@ -83,6 +69,17 @@ "Comment": "技能列表", "ArraySplitter": "|" }, + { + "Name": "Buff", + "Type": "int", + "Comment": "增益" + }, + { + "Name": "TagList", + "Type": "string", + "Comment": "标记", + "ArraySplitter": "|" + }, { "Name": "Multi", "Type": "int", @@ -103,19 +100,12 @@ { "Name": "ServerIP", "Type": "string", - "Comment": "服务器IP", - "Tags": [ - "e", - "f" - ] + "Comment": "服务器IP" }, { "Name": "ServerPort", "Type": "uint16", - "Comment": "服务器端口", - "Tags": [ - "g" - ] + "Comment": "服务器端口" }, { "Name": "GroupID", @@ -124,6 +114,17 @@ "ArraySplitter": ";" } ] + }, + { + "Name": "ExtendData", + "Type": "Struct", + "Fields": [ + { + "Name": "Additive", + "Type": "float", + "Comment": "附加" + } + ] } ] } \ No newline at end of file diff --git a/v3/example/lua/table_gen.lua b/v3/example/lua/table_gen.lua index 7000adbb..5b39a265 100644 --- a/v3/example/lua/table_gen.lua +++ b/v3/example/lua/table_gen.lua @@ -1,14 +1,18 @@ -- Generated by github.com/davyxu/tabtoy --- Version: 3.0.1 +-- Version: 3.0.0 local tab = { ExampleData = { - { ID = 100, Name = "扎克镇", Rate = 3.14, Type = 2, Skill = {3,1,2}, Multi = {1,2,3}, }, - { ID = 200, Name = "阿努比斯神庙", Rate = 1.2, Type = 3, Skill = {100,0,90}, Multi = {4,0}, }, - { ID = 300, Name = "花村", Rate = 79.4, Type = 3, Skill = {0}, Multi = {}, }, - { ID = 400, Name = "艾兴瓦尔德", Rate = 0.63, Type = 4, Skill = {0}, Multi = {}, }, + { ID = 100, Name = "扎克镇", Rate = 3.14, Type = 2, Skill = [3,1,2], Buff = 100, TagList = ["a","b"], Multi = [1,3], }, + { ID = 200, Name = "阿努比斯神庙", Rate = 1.2, Type = 1, Skill = [100,0,90], Buff = 1, TagList = ["c"], Multi = [4,0], }, + { ID = 300, Name = "花村", Rate = 79.4, Type = 3, Skill = [], Buff = 0, TagList = [], Multi = [], }, + { ID = 400, Name = "艾兴瓦尔德", Rate = 0.63, Type = 4, Skill = [], Buff = 0, TagList = [], Multi = [], }, + }, + ExtendData = { + { Additive = 1.1, }, + { Additive = 1.2, }, }, ExampleKV = { - { ServerIP = "8.8.8.8", ServerPort = 1024, GroupID = {10,20}, }, + { ServerIP = "8.8.8.8", ServerPort = 1024, GroupID = [10,20], }, }, } diff --git a/v3/example/xlsx/Data.xlsx b/v3/example/xlsx/Data.xlsx index a3cd8aac37f934bc43d2628d370b12342ca3160e..1ff642996aa8e3ecc1c32f44b4dbb2757e2dff95 100644 GIT binary patch delta 5330 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 Vi~b(qgo3rs?$us{&{tIg$@!|jg diff --git a/v3/example/xlsx/Data2.xlsx b/v3/example/xlsx/Data2.xlsx index 064f4c2f60d6c133c1c1b58a2d88f0ae190bb379..f20febcab9bfdd8a32143bceae2d94cb947fb294 100644 GIT binary patch literal 9122 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 literal 9216 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 delta 5128 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 diff --git a/v3/example/xlsx/KV.xlsx b/v3/example/xlsx/KV.xlsx index 4117a35e84bcfbdcd1645415a9c8c581b7144624..02971e4799f4f2617a46520280161790630d7ce8 100644 GIT binary patch delta 5229 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 ABLDyZ diff --git a/v3/example/xlsx/Run.sh b/v3/example/xlsx/Run.sh index 1679feb5..7e4b7ee5 100755 --- a/v3/example/xlsx/Run.sh +++ b/v3/example/xlsx/Run.sh @@ -15,6 +15,11 @@ go build -v -o ./tabtoy github.com/davyxu/tabtoy -java_out=../java/src/main/java/main/Table.java \ -package=main +if [ $? -ne 0 ] ; then + read -rsp $'Errors occurred...\n' ; + exit 1 +fi + cp ../json/table_gen.json ../java/cfg rm -f tabtoy \ No newline at end of file diff --git a/v3/example/xlsx/Type.xlsx b/v3/example/xlsx/Type.xlsx index 866ed9868665529cc4f9cc090d7d066561af20b3..cc9be9d7f2a315af84683cb9cadef940a8c6a946 100644 GIT binary patch delta 6036 zcmZ8l2RPipwrBNT6K%Cvy|?I{=ru~T5JGgK_rKnjD9h?Z5S=K|yG25X5=5^XUDW7Y zx$oV3-+eRR%zQKRJ7>q+>x&uoyIq%E_D~YpF2rzJ$%lP znb5A__tuo=YYqTp(N4z$b+juHNv2#q{5{}4ZoVH(Bm^ow%0zl^lzym`9^{J&eG!B6t zc9Cu~=eYIN!qLN`F}fP7>8jh@Cgzy7$(5GM04<8PXuVMEK;pSUY0jGM+dkXKxCjI^ z>09rHt%9C-_H+5A`P#0ldCMRa);HME6+dGSYYndW-e*Bw$OpvnoMpNVo0+N zq}z!9rt50A$dmj%{FL4w9qReg_<4^IBe6q5J2_}__r>k@nV41oHwD28U2qX}i#c`u^dP)~{VSW=B*Z0yTx^8uZkY1U zpp;6w%^Y6Qg{q^T45Ea|qRZi)bFD_yW1yhyQ^KI=^gyP$>zXKe)NiA?dtziTHs%$( zrBITrbi;&Q8~uzuA2SEzEP^}t@+^SVdPbV{$t0fIvZQov{!f;olN$Q|alcJ3Sb9n1 z@H6X~)so5uWJ!AD^|?hh?|JoP%xQyqA~KeDfxi817Y}gn9L%#j^Q*hX?R{^VaWfWU zx$<|%IslD#!dBn#23`4&jd>C1uF|6YW4T}JF7+d2R{^?Zf2FK^Gvn3TyEJNKaQ>SG z-ukAn{0J_+6Kjt5_alro)CT+3=jvzPUj9+F<#&|kr$`d>#1WPIILV6Pj|)&;!^e4h z)U?R(bIXMKFDeCe#!4n#ody=~-7vxfMiW~u#sLB&uNdfe@y!!I&+05)@7B{^V#I+Y z&$Md-8=lOgvbG!_qm_Vt?#(tZS7Z88*=6u*uyrC%o5!kb^bPF9!@Au^@#+SVC`lHG z<VY6LNw2$eId_DBg|E-1wR`&tqjgyZ2%ZZE^!?=l2BGj5coDj-1cU z0!Kkt-sHQ-7p|RT(UEvwJhS;ov5m`NIa#BRh1rdEhI9p>c5$VpQQH~ziNr{W(7d5( z+O5~Q@#=Ek_H5Z2yqYUb4gz$VE(?y%w&_m~O+UXqF8Yq~r^+3Z#=n8^g(qov(Gz%VNJnRaIk*}cP#8@PRR$$08%d+s%mqu9KA>wM5 zUa6M(!ymHwIu%#WJm@}L(w#DFDbhsRd5L1bC0=D1kh4OEi~syxUEwH#*j3LUwNrf9 z$RQ~l`&6$Ydxd!+e1*A^xQY-9U?hA3Mu@7!ckB5`6cL7?dZl*nu<^^8zT+iPr!|>G zRiZRhPR23$V;afU_HS&8p9q931T{0YTY#Nk?i&7pWidgbD#d6-vOPBiM~KGgTXLZ^ z_#kj~4ak^2z3!z*+J&~>M!5&+K7ZIH0-do_Q6uwt!vPu)$LFc~l$=rUIpdHAIN-bizKSM#mjDz;FKDt3OQ`TTz_)rYF|+3_C z%hnONtcOROce??Rpd8P1mTuo6Z>$ZmYpN8!ZYh<4Uj;1B6|+FP^e_g(uSzOdO91pP zUWUl|-4lwa`^)Qvrxswc3o6m$NH6R*84bI~O}mcu>6DbeOKF&@GAXg+j<|Z?%anqE zsD49uv4Ld8J|TNb-F)IUa8f^4H$4F1bBDB+o0q%tH{H6;!U)IdFfBILEA8kmQ%U9U2Uf4fRI)N2_{P= z5ji632RVXPfub|@V22#0U`1yRDcs)G*oNPRJe4U-9%p4Qv zUr^n>Lja%jdZObp5$R?Nxf}h_Pz*8=nY9}~!`Jl%p-H%l0-s7%DtO4@ zX)nADhOor(@WLE?=5GZxvjW$65A&cwqi^4lHEDuNn1o~3&)dIWw*%=OUf$Jtf6S3^ zT72-bBmBp{nrdywyJfHTLfh?Yk;fFAR>!R%)Tq%_l#o6=r35mFJF|N>eKnBkr zskKQgeR4hP3!ONMehK{KqB>%Z3_Qu@G5ev0YhQ)*K^@XWX3J1rt`j`>194XKK`A9IhEThHl8*XWRlS%ObQ#hu_>6=C-UhN9~5@nBrlVY@7O))lfbq*iw-k9QBFyMAlmnMUi6 zNi3Rgl6$dy241G&mKQPVcy^1+ z5~p4<6Q`N!#V*$9DV3^JkI`>c#x)clmo`=2!r$z!ty@@G9Nix#su)_sD?A)^GD+>l zI<5Bz_pzZaVNIO|4_^)HFJU+}cbK0Uqp^|;UMqFQN5EanU4cqBJ#E3aNHF9mYrXY| zkM_#a-Nt9Lh&IZ5#rW{E{PMD>MCegA)+8oEj!KoM{hG}#zl{1_mlFtW*{c=1Ul&R* z+$+T5Ii_J%QCCI%(f({f*bHdogyPKQg?rzKVi+wQimt3@}L8&xEfJ2*tO?tnkO9l7-9z7o4T z8L1GhF*1dhW#yEU588Gv#XpU*yHp7R$&UQV% z6T7d8y!V%;-6$Uv5z5klKj?xPRvYej4><;=0W+O&bn~-4ho|n-RxA`PHO5$nTok{i zqJzgG%|#B<7wwsCLQNY zi2(K`ewI1Hd#&3ipTWK6`o>BEIBh)1oP$<7DAA%m9U6vE6`1+*^4r#OTNcJgmfm(Q zdPN0UzN1tPkK~+NQ$xuc0KJL%lD5s_^7Z4By24!|B6Eqxa5!h<5Sz!We5UaXH+gci zTY-k5IFo7Qry_WrIbLQl9>jLvjDexnJrqzhq@jqY$Wb2-Lu$7xW{L@Iz7>;kcpc?V zI@`Q~F5v!EwVgU$54s+xEXFFAvSQjS#fe{LMco)ceWjq#Q2AtwuSrR4N2@5O# z_h)lnvf4jt&CkVm1cJw)ZA^U;R-SX~qjKFK&N&_BO@T4f7xTrgsxu1Gdj}2Xn_qz4 zc{-=bdATjmF%|$zdhYd`yM}Z-c+L^S{s#r@WAC&-Ut%PxC z0q;$ihSJaF66XiVb?gtzBPm0y@%Z&$fc1R|v8R6%Tt|CbuGaJ6%XhN98Y4Yow~SDI zWUKS;Eyg#h_tLm|VG^_5tWHnG>3YHdtAWC}QIB!-=;A-1P@%)il7tg+HO`?DT*r2d zC#f}QAzbn}>Gfd^$2`AFO(qDdSA^qO(<_dYSklA4C0F1YplD=Ha>wT0a>qc1gazPv+1}1>wQp3UN)c6v(aVeYbOgawP$x<{u#hrf$>%RRS zf=T(i1a$sUYdaaT|83B;UGPgOn`w)C(NoQ^w=_tgVz!V|eaG?OvtW??9w19aa+XXB zYL4I3e;q~^#M*VIfeKggEqwnb&g(eP-t%>| ze6D1hOzSmYiflhrwY#1Dks|~(mzFhDJDfH2-NB;Y-RaVnQCCjzq4b+4)V6%)7ea1& z6EEzZWC_(i^9=M9pB>ujq98F5Dzk0s17#tk>0BVu)500xOZyn~WZ-k;3tiq}YW|Il zyUl~syZR$n>%{kIx>{;GeH1_-=H5G*Aek_zA&wa1jpsNQXTBy+XO?uc?@^BgjH=3N zOU0h{e%E#K#K$_#Y74~)=W`i2RGhT#LWP`3H9e~TqVQyU5YS;bElr|S+n8-G>VORb zv>oR>kfDpduE8)X;9@L4RaF#j2US84hxODUM!yznhh!b?E8}=sQ5qD#RZKu5(pyJ- z3PtM2%5#uU#u!ObCb%IKo}}(1ybxLHu^rjE=(b9EQJ!r;%kOOoJ+Sc{)QZf%S+%Al z3{%aLo7%lOiQ&-XdKU7M#r-Iqf`Z73gx}NBkdcH6a1XcvHlqszx@ZQQ@R!uNyR5VcP8rc6*8Its9q%`CMrL8a+*i2*cw}!~Y?p@?>uFqR2`W|t?F);i< zGF0S+(c0_R{Z@*3<=RU!9k5#2Av5F2aCZhl63-jB4nhfjx-v|GeC3swx~!(Z~T)jsV*yb1gZPF zIBKr2Hcxj-29rHQHSt*ZF+umGx++>(;3r$eMTB*Kiml$IbUbB!RO1`7S{}5Z4x6RPCt|nXz+s1a>^8`m>-)Q~zA8tWLH^)AV0Ax~7 zrB>%_p+FB5BAuQJ0sI`>?Gmg2FOU1~iAL(QjsbYV{1kV6Yg3njut~u6HQacdqbgrc z%0fXV+ZU-XY#S_I``Z%)tep4m6H2Zj&;7Lq^KOq6>z$s-;01Q>chMa-zS0#fey!W z?#fx3lLg<|WsmPjzr3~zX$wzU8-nW}e_{%ja#YK3S*X6(sgCMc6wxnaJbyGqT${8` z;#A74G39r1C7i4G5rDKrP&?$+_L^%JW=eXKK$0sr+hUmWgS84V=$W9u_-(5T z7uAYwg(+qg4Fq1wW)zGr8m5K(tN{fAARk+U=OvA0f`U6v&y*F+tv^=Z!eWn?j01nD zf!dA3`D?pK&X-QESnv zcpfF2x*a}vXH@TMl96fROlo&ZJj)GTaR1$cufknmtH;#FUi9XIiW^N9>#TRQm=6OL%q0c5CyA zU(I71iTZlrfM{8N$1~9jN{fS|A^Mm1-*!!J7Gr$AE4DB(v(D6TCWt4vYddieL^b)q z;46=ZL;IX!KD5x}y_7Xq&0`iiYU7u7mJ7;KmL5__aBv+c3@S}TtJ@hKWW)3tzelH# zL2MN3bGrgW-+5OjZ1&!$5vRxDlR3_DQUd0i24&3{^uu+T9e*t5O^!tb?m_?UDDmaF z?yw;+Eug6l;wSz~@kQGnOhjU!_wvN*GErE6SZi^4GaD6L%*}Hb@Wv6kV)rEY1yMWj_y|MhU-(t3zKiMpPJP8J>H!wBnU zcmxZ2!hya_hk^o=gFJ@yJfQ}m(Zd#>r2H=+fCOULEkq1tf(sL676ygl!d#h|!GEuu^}(8jheGsEZU52-rG@7Mh5uN(6jyeYB-*J+MjP+m}5!2t^KL9?1KrR3P delta 5819 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 0 { sb.WriteString(",") } @@ -30,6 +29,12 @@ func WrapValue(globals *model.Globals, value string, valueType *model.TypeDefine return sb.String() } else { + + var value string + if cell != nil { + value = cell.Value + } + return gen.WrapSingleValue(globals, valueType, value) } } @@ -49,10 +54,10 @@ func init() { if valueCell != nil { - return WrapValue(globals, valueCell.Value, header) + return WrapValue(globals, valueCell, header) } else { // 这个表中没有这列数据 - return WrapValue(globals, "", header) + return WrapValue(globals, nil, header) } } diff --git a/v3/gen/jsondata2/gen.go b/v3/gen/jsondata2/gen.go index 872882f5..44160c03 100644 --- a/v3/gen/jsondata2/gen.go +++ b/v3/gen/jsondata2/gen.go @@ -5,16 +5,16 @@ import ( "github.com/davyxu/tabtoy/util" "github.com/davyxu/tabtoy/v3/model" "strconv" - "strings" ) -func wrapValue(globals *model.Globals, value string, valueType *model.TypeDefine) interface{} { +func wrapValue(globals *model.Globals, valueCell *model.Cell, valueType *model.TypeDefine) interface{} { if valueType.IsArray() { var vlist = make([]interface{}, 0) // 空的单元格,导出空数组,除非强制指定填充默认值 - if value != "" { - for _, elementValue := range strings.Split(value, valueType.ArraySplitter) { + if valueCell != nil { + + for _, elementValue := range valueCell.ValueList { vlist = append(vlist, wrapSingleValue(globals, valueType, elementValue)) } @@ -23,6 +23,12 @@ func wrapValue(globals *model.Globals, value string, valueType *model.TypeDefine return vlist } else { + + var value string + if valueCell != nil { + value = valueCell.Value + } + return wrapSingleValue(globals, valueType, value) } } @@ -110,14 +116,7 @@ func Generate(globals *model.Globals) (data []byte, err error) { // 在单元格找到值 valueCell := tab.GetCell(row, col) - var value interface{} - if valueCell != nil { - - value = wrapValue(globals, valueCell.Value, header) - } else { - // 这个表中没有这列数据 - value = wrapValue(globals, "", header) - } + var value = wrapValue(globals, valueCell, header) rowData[header.FieldName] = value } diff --git a/v3/gen/luasrc/func.go b/v3/gen/luasrc/func.go index dde48024..3c532bc9 100644 --- a/v3/gen/luasrc/func.go +++ b/v3/gen/luasrc/func.go @@ -9,15 +9,14 @@ import ( var UsefulFunc = template.FuncMap{} -func WrapValue(globals *model.Globals, value string, valueType *model.TypeDefine) string { +func WrapValue(globals *model.Globals, cell *model.Cell, valueType *model.TypeDefine) string { if valueType.IsArray() { var sb strings.Builder - sb.WriteString("{") + sb.WriteString("[") - // 空的单元格,导出空数组,除非强制指定填充默认值 - if value != "" { - for index, elementValue := range strings.Split(value, valueType.ArraySplitter) { + if cell != nil { + for index, elementValue := range cell.ValueList { if index > 0 { sb.WriteString(",") } @@ -25,15 +24,19 @@ func WrapValue(globals *model.Globals, value string, valueType *model.TypeDefine } } - sb.WriteString("}") + sb.WriteString("]") return sb.String() } else { + + var value string + if cell != nil { + value = cell.Value + } + return gen.WrapSingleValue(globals, valueType, value) } - - return value } func init() { @@ -51,10 +54,10 @@ func init() { if valueCell != nil { - return WrapValue(globals, valueCell.Value, header) + return WrapValue(globals, valueCell, header) } else { // 这个表中没有这列数据 - return WrapValue(globals, "", header) + return WrapValue(globals, nil, header) } } diff --git a/v3/model/cell.go b/v3/model/cell.go index 2d465359..dccf46ca 100644 --- a/v3/model/cell.go +++ b/v3/model/cell.go @@ -6,10 +6,11 @@ import ( ) type Cell struct { - Value string - Row int // base 0 - Col int // base 0 - Table *DataTable + Value string + ValueList []string // merge之后, 数组值保存在这里 + Row int // base 0 + Col int // base 0 + Table *DataTable } // 全拷贝 @@ -28,5 +29,12 @@ func (self *Cell) String() string { sheet = self.Table.SheetName } - return fmt.Sprintf("'%s' @%s|%s(%s)", self.Value, file, sheet, util.R1C1ToA1(self.Row+1, self.Col+1)) + var value string + if len(self.ValueList) > 0 { + value = fmt.Sprintf("%+v", self.ValueList) + } else { + value = self.Value + } + + return fmt.Sprintf("'%s' @%s|%s(%s)", value, file, sheet, util.R1C1ToA1(self.Row+1, self.Col+1)) } diff --git a/v3/model/datatab.go b/v3/model/datatab.go index 3cb21b91..8db332fd 100644 --- a/v3/model/datatab.go +++ b/v3/model/datatab.go @@ -20,27 +20,11 @@ type DataTable struct { Headers []*HeaderField } -// 重复列在表中数量, 重复列可以将数组拆在多个列中填写 -func (self *DataTable) RepeatedFieldCount(field *HeaderField) (ret int) { - - for _, hf := range self.Headers { - if hf.TypeInfo == field.TypeInfo { - ret++ - } - } - - return -} - // 重复列在表中的索引, 相对于重复列的数量 -func (self *DataTable) RepeatedFieldIndex(field *HeaderField) (ret int) { +func (self *DataTable) ArrayFieldCount(field *HeaderField) (ret int) { for _, hf := range self.Headers { - if hf.TypeInfo == field.TypeInfo { - - if hf == field { - break - } + if hf.TypeInfo != nil && hf.TypeInfo.FieldName == field.TypeInfo.FieldName { ret++ } diff --git a/v3/report/errid.go b/v3/report/errid.go index e645f893..0cbb1841 100644 --- a/v3/report/errid.go +++ b/v3/report/errid.go @@ -6,19 +6,20 @@ type ErrorLanguage struct { var ( ErrorByID = map[string]*ErrorLanguage{ - "HeaderNotMatchFieldName": {CHS: "表头与字段不匹配"}, - "HeaderFieldNotDefined": {CHS: "表头字段未定义"}, - "DuplicateHeaderField": {CHS: "表头字段重复"}, - "DuplicateKVField": {CHS: "键值表字段重复"}, - "UnknownFieldType": {CHS: "未知字段类型"}, - "DuplicateTypeFieldName": {CHS: "类型表字段重复"}, - "EnumValueEmpty": {CHS: "枚举值空"}, - "DuplicateEnumValue": {CHS: "枚举值重复"}, - "UnknownEnumValue": {CHS: "未知的枚举值"}, - "InvalidTypeTable": {CHS: "非法的类型表"}, - "HeaderTypeNotFound": {CHS: "表头类型找不到"}, - "DuplicateValueInMakingIndex": {CHS: "创建索引时发现重复值"}, - "UnknownInputFileExtension": {CHS: "未知的输入文件扩展名"}, - "DataMissMatchTypeDefine": {CHS: "数据与定义类型不匹配"}, + "HeaderNotMatchFieldName": {CHS: "表头与字段不匹配"}, + "HeaderFieldNotDefined": {CHS: "表头字段未定义"}, + "DuplicateHeaderField": {CHS: "表头字段重复"}, + "DuplicateKVField": {CHS: "键值表字段重复"}, + "UnknownFieldType": {CHS: "未知字段类型"}, + "DuplicateTypeFieldName": {CHS: "类型表字段重复"}, + "EnumValueEmpty": {CHS: "枚举值空"}, + "DuplicateEnumValue": {CHS: "枚举值重复"}, + "UnknownEnumValue": {CHS: "未知的枚举值"}, + "InvalidTypeTable": {CHS: "非法的类型表"}, + "HeaderTypeNotFound": {CHS: "表头类型找不到"}, + "DuplicateValueInMakingIndex": {CHS: "创建索引时发现重复值"}, + "UnknownInputFileExtension": {CHS: "未知的输入文件扩展名"}, + "DataMissMatchTypeDefine": {CHS: "数据与定义类型不匹配"}, + "ArrayMultiColumnDefineNotMatch": {CHS: "数组类型多列跨表定义不一致"}, } ) diff --git a/v3/tests/data_test.go b/v3/tests/data_test.go index 84d8f053..409158d7 100644 --- a/v3/tests/data_test.go +++ b/v3/tests/data_test.go @@ -71,35 +71,72 @@ func TestArrayList(t *testing.T) { helper.WriteIndexTableHeader(indexSheet) helper.WriteRowValues(indexSheet, "类型表", "", "Type") - helper.WriteRowValues(indexSheet, "数据表", "", "TestData") + helper.WriteRowValues(indexSheet, "数据表", "TestData", "TestData") + helper.WriteRowValues(indexSheet, "数据表", "TestData", "TestData2") typeSheet := emu.CreateCSVFile("Type") helper.WriteTypeTableHeader(typeSheet) helper.WriteRowValues(typeSheet, "表头", "TestData", "ID", "ID", "int", "", "") helper.WriteRowValues(typeSheet, "表头", "TestData", "技能列表", "SkillList", "int", "|", "") helper.WriteRowValues(typeSheet, "表头", "TestData", "名字列表", "NameList", "string", "|", "") + helper.WriteRowValues(typeSheet, "表头", "TestData", "ID列表", "IDList", "int32", "|", "") // 单列 dataSheet := emu.CreateCSVFile("TestData") - helper.WriteRowValues(dataSheet, "ID", "技能列表", "技能列表", "技能列表", "名字列表", "名字列表") - helper.WriteRowValues(dataSheet, "1", "100", "200", "300", "", "") - helper.WriteRowValues(dataSheet, "2", "1", "", "3", "", "") // 多列数组补0 - helper.WriteRowValues(dataSheet, "3", "", "20", "30", "", "") // 多列数组补0 - helper.WriteRowValues(dataSheet, "4", "", "", "", "", "") // 多列数组补0 + helper.WriteRowValues(dataSheet, "ID", "技能列表", "技能列表", "技能列表", "名字列表", "名字列表", "ID列表") + helper.WriteRowValues(dataSheet, "1", "100", "200", "300", "", "", "") + helper.WriteRowValues(dataSheet, "2", "1", "", "3", "", "", "") // 多列数组补0 + helper.WriteRowValues(dataSheet, "3", "", "20", "30", "", "", "") // 多列数组补0 + helper.WriteRowValues(dataSheet, "4", "", "", "", "", "", "") // 多列数组补0 + + // 数组列多列情况, 又在不同的表中可能存在不同数量列的情况 + dataSheet2 := emu.CreateCSVFile("TestData2") + helper.WriteRowValues(dataSheet2, "ID", "技能列表", "技能列表", "技能列表") + helper.WriteRowValues(dataSheet2, "5", "1", "1") + helper.WriteRowValues(dataSheet2, "6", "2", "1") emu.VerifyData(` { - "@Tool": "github.com/davyxu/tabtoy", - "@Version": "testver", - "TestData":[ - { "ID": 1, "SkillList": [100,200,300], "NameList":["", ""] }, - { "ID": 2, "SkillList": [1,0,3], "NameList":["", ""] }, - { "ID": 3, "SkillList": [0,20,30], "NameList":["", ""] }, - { "ID": 4, "SkillList": [0,0,0], "NameList":["", ""] } - ] - } + "@Tool": "github.com/davyxu/tabtoy", + "@Version": "testver", + "TestData":[ + { "ID": 1, "SkillList": [100,200,300], "NameList": ["",""], "IDList": [] }, + { "ID": 2, "SkillList": [1,0,3], "NameList": ["",""], "IDList": [] }, + { "ID": 3, "SkillList": [0,20,30], "NameList": ["",""], "IDList": [] }, + { "ID": 4, "SkillList": [0,0,0], "NameList": ["",""], "IDList": [] }, + { "ID": 5, "SkillList": [1,1,0], "NameList": [], "IDList": [] }, + { "ID": 6, "SkillList": [2,1,0], "NameList": [], "IDList": [] } + ] + } `) } +func TestArrayMultiColumnDefineNotMatch(t *testing.T) { + emu := NewTableEmulator(t) + indexSheet := emu.CreateCSVFile("Index") + + helper.WriteIndexTableHeader(indexSheet) + helper.WriteRowValues(indexSheet, "类型表", "", "Type") + helper.WriteRowValues(indexSheet, "数据表", "TestData", "TestData") + helper.WriteRowValues(indexSheet, "数据表", "TestData", "TestData2") + + typeSheet := emu.CreateCSVFile("Type") + helper.WriteTypeTableHeader(typeSheet) + helper.WriteRowValues(typeSheet, "表头", "TestData", "ID", "ID", "int", "", "") + helper.WriteRowValues(typeSheet, "表头", "TestData", "技能列表", "SkillList", "int", "|", "") + + dataSheet := emu.CreateCSVFile("TestData") + helper.WriteRowValues(dataSheet, "ID", "技能列表", "技能列表") + helper.WriteRowValues(dataSheet, "1", "100", "200") + + // 数组列多列情况, 又在不同的表中可能存在不同数量列的情况 + dataSheet2 := emu.CreateCSVFile("TestData2") + helper.WriteRowValues(dataSheet2, "ID", "技能列表") + helper.WriteRowValues(dataSheet2, "5", "") + helper.WriteRowValues(dataSheet2, "6", "") + + emu.MustGotError("TableError.ArrayMultiColumnDefineNotMatch 数组类型多列跨表定义不一致 | ") +} + // 重复性检查 func TestRepeatCheck(t *testing.T) { diff --git a/v3/tests/emulator.go b/v3/tests/emulator.go index 4545444f..013798fa 100644 --- a/v3/tests/emulator.go +++ b/v3/tests/emulator.go @@ -5,7 +5,7 @@ import ( "github.com/davyxu/tabtoy/v3/compiler" "github.com/davyxu/tabtoy/v3/gen" "github.com/davyxu/tabtoy/v3/gen/gosrc" - "github.com/davyxu/tabtoy/v3/gen/jsontext" + "github.com/davyxu/tabtoy/v3/gen/jsondata" "github.com/davyxu/tabtoy/v3/helper" "github.com/davyxu/tabtoy/v3/model" "io/ioutil" diff --git a/v3/tests/type_test.go b/v3/tests/type_test.go index 98919902..86358996 100644 --- a/v3/tests/type_test.go +++ b/v3/tests/type_test.go @@ -137,6 +137,39 @@ func TestInvalidEnumValue(t *testing.T) { emu.MustGotError("TableError.UnknownEnumValue 未知的枚举值 | ActorType 'Arch2' @TestData|(A2)") } +// 枚举值为空 +func TestEmptyEnumValue(t *testing.T) { + + emu := NewTableEmulator(t) + indexSheet := emu.CreateCSVFile("Index") + + helper.WriteIndexTableHeader(indexSheet) + helper.WriteRowValues(indexSheet, "类型表", "", "Type") + helper.WriteRowValues(indexSheet, "数据表", "", "TestData") + + typeSheet := emu.CreateCSVFile("Type") + helper.WriteTypeTableHeader(typeSheet) + helper.WriteRowValues(typeSheet, "枚举", "ActorType", "", "None", "int", "", "1") + helper.WriteRowValues(typeSheet, "枚举", "ActorType", "", "Arch", "int", "", "2") + + helper.WriteRowValues(typeSheet, "表头", "TestData", "ID", "ID", "int", "", "") + helper.WriteRowValues(typeSheet, "表头", "TestData", "角色类型", "Type", "ActorType", "", "") + + dataSheet := emu.CreateCSVFile("TestData") + helper.WriteRowValues(dataSheet, "ID", "角色类型") + helper.WriteRowValues(dataSheet, "1", "") + + emu.VerifyData(` +{ + "@Tool": "github.com/davyxu/tabtoy", + "@Version": "testver", + "TestData":[ + { "ID": 1, "Type": 1 } + ] +} +`) +} + func TestBasicType(t *testing.T) { emu := NewTableEmulator(t)