【特性】新增生成类型 cfg code_rust_json(多态支持有一些问题)
parent
dad7fa0ea8
commit
c29c00bbe3
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
## 介绍
|
## 介绍
|
||||||
|
|
||||||
目前已经存在很多导表工具(如tabtoy、xls2json),它们功能多为excel文件到其他格式的转换工具及简单代码生成器,勉强满足中小类型项目的需求。
|
目前存在的配置工具,它们功能多为excel文件到json之类格式的转换工具及简单代码生成器,勉强满足中小类型项目的需求。
|
||||||
在中大型游戏项目中,基本都会有技能、行为树之类的复杂功能。这些功能有非常复杂的数据结构,往往使用自定义编辑器制作,并以json、xml等文件格式保存。就算常规的excel表,也经常出现复杂的数据结构需求。这些简单工具面对此类需求要么无法支持,要么就强迫策划和程序使用拆表等奇技淫巧,严重影响开发效率。
|
在中大型游戏项目中,基本都会有技能、行为树之类的复杂功能。这些功能有非常复杂的数据结构,往往使用自定义编辑器制作,并以json、xml等文件格式保存。就算常规的excel表,也经常出现复杂的数据结构需求。这些简单工具面对此类需求要么无法支持,要么就强迫策划和程序使用拆表等奇技淫巧,严重影响开发效率。
|
||||||
|
|
||||||
luban相较于常规的excel导表工具有以下核心优势:
|
luban相较于常规的excel导表工具有以下核心优势:
|
||||||
|
|
@ -77,6 +77,7 @@ luban相较于常规的excel导表工具有以下核心优势:
|
||||||
- js 和 typescript (3.0+)
|
- js 和 typescript (3.0+)
|
||||||
- python (3.0+)
|
- python (3.0+)
|
||||||
- erlang (18+)
|
- erlang (18+)
|
||||||
|
- rust (1.5+)
|
||||||
- 支持主流引擎和平台
|
- 支持主流引擎和平台
|
||||||
- unity + c#
|
- unity + c#
|
||||||
- unity + [tolua](https://github.com/topameng/tolua)、[xlua](https://github.com/Tencent/xLua)
|
- unity + [tolua](https://github.com/topameng/tolua)、[xlua](https://github.com/Tencent/xLua)
|
||||||
|
|
@ -96,8 +97,6 @@ luban相较于常规的excel导表工具有以下核心优势:
|
||||||
- 其他所有支持lua的引擎和平台
|
- 其他所有支持lua的引擎和平台
|
||||||
- 其他所有支持js的引擎和平台
|
- 其他所有支持js的引擎和平台
|
||||||
|
|
||||||
-----
|
|
||||||
|
|
||||||
## 快速上手
|
## 快速上手
|
||||||
|
|
||||||
以创建一个道具表为例
|
以创建一个道具表为例
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,11 @@ namespace Luban.Common.Utils
|
||||||
return module.Replace('.', '_') + "_" + name;
|
return module.Replace('.', '_') + "_" + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string MakeRustFullName(string module, string name)
|
||||||
|
{
|
||||||
|
return MakeGoNamespace(module) + "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
public static string MakeNamespace(string module, string subModule)
|
public static string MakeNamespace(string module, string subModule)
|
||||||
{
|
{
|
||||||
if (module.Length == 0)
|
if (module.Length == 0)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Luban.Job.Cfg
|
||||||
[Option("output_data_json_monolithic_file", Required = false, HelpText = "output monolithic json file")]
|
[Option("output_data_json_monolithic_file", Required = false, HelpText = "output monolithic json file")]
|
||||||
public string OutputDataJsonMonolithicFile { get; set; }
|
public string OutputDataJsonMonolithicFile { get; set; }
|
||||||
|
|
||||||
[Option("gen_types", Required = true, HelpText = "code_cs_bin,code_cs_json,code_cs_unity_json,code_lua_bin,code_java_bin,code_java_json,code_go_bin,code_go_json,code_cpp_bin,code_python3_json,code_typescript_bin,code_typescript_json,data_bin,data_lua,data_json,data_json2,data_json_monolithic,data_resources,data_template . can be multi")]
|
[Option("gen_types", Required = true, HelpText = "code_cs_bin,code_cs_json,code_cs_unity_json,code_lua_bin,code_java_bin,code_java_json,code_go_bin,code_go_json,code_cpp_bin,code_python3_json,code_typescript_bin,code_typescript_json,code_rust_json,data_bin,data_lua,data_json,data_json2,data_json_monolithic,data_resources,data_template . can be multi")]
|
||||||
public string GenType { get; set; }
|
public string GenType { get; set; }
|
||||||
|
|
||||||
[Option("template_name", Required = false, HelpText = "template name. use with gen_types=data_template")]
|
[Option("template_name", Required = false, HelpText = "template name. use with gen_types=data_template")]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
using Luban.Job.Cfg.Defs;
|
||||||
|
using Luban.Job.Common.Defs;
|
||||||
|
using Luban.Job.Common.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Luban.Job.Cfg.Generate
|
||||||
|
{
|
||||||
|
[Render("code_rust_json")]
|
||||||
|
class RustCodeJsonRender : CodeRenderBase
|
||||||
|
{
|
||||||
|
public override void Render(GenContext ctx)
|
||||||
|
{
|
||||||
|
string genType = ctx.GenType;
|
||||||
|
var args = ctx.GenArgs;
|
||||||
|
ctx.Render = this;
|
||||||
|
ctx.Lan = RenderFileUtil.GetLanguage(genType);
|
||||||
|
|
||||||
|
var lines = new List<string>();
|
||||||
|
GenerateCodeMonolithic(ctx, "mod.rs", lines, ls =>
|
||||||
|
{
|
||||||
|
var template = StringTemplateUtil.GetTemplate("config/rust_json/mod_header");
|
||||||
|
var result = template.RenderCode(ctx.ExportTypes);
|
||||||
|
ls.Add(result);
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Render(DefConst c)
|
||||||
|
{
|
||||||
|
return RenderUtil.RenderRustConstClass(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Render(DefEnum e)
|
||||||
|
{
|
||||||
|
return RenderUtil.RenderRustEnumClass(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Render(DefBean b)
|
||||||
|
{
|
||||||
|
var template = StringTemplateUtil.GetTemplate("config/rust_json/bean");
|
||||||
|
var result = template.RenderCode(b);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Render(DefTable p)
|
||||||
|
{
|
||||||
|
var template = StringTemplateUtil.GetTemplate("config/rust_json/table");
|
||||||
|
var result = template.RenderCode(p);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string RenderService(string name, string module, List<DefTable> tables)
|
||||||
|
{
|
||||||
|
var template = StringTemplateUtil.GetTemplate("config/rust_json/tables");
|
||||||
|
var result = template.RenderCode(new
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Namespace = module,
|
||||||
|
Tables = tables,
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
using Luban.Job.Common.Types;
|
||||||
|
using Luban.Job.Common.TypeVisitors;
|
||||||
|
|
||||||
|
namespace Luban.Job.Cfg.TypeVisitors
|
||||||
|
{
|
||||||
|
class RustJsonConstructorVisitor : DecoratorFuncVisitor<string, string>
|
||||||
|
{
|
||||||
|
public static RustJsonConstructorVisitor Ins { get; } = new();
|
||||||
|
|
||||||
|
public override string DoAccept(TType type, string jsonFieldName)
|
||||||
|
{
|
||||||
|
if (type.IsNullable)
|
||||||
|
{
|
||||||
|
return $"if !{jsonFieldName}.is_null() {{ Some({type.Apply(RustJsonUnderingConstructorVisitor.Ins, jsonFieldName)}) }} else {{ None }}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return type.Apply(RustJsonUnderingConstructorVisitor.Ins, jsonFieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//public override string Accept(TBean type, string bytebufName, string fieldName)
|
||||||
|
//{
|
||||||
|
// return type.Apply(TypescriptJsonUnderingConstructorVisitor.Ins, bytebufName, fieldName);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
using Luban.Job.Cfg.Datas;
|
||||||
|
using Luban.Job.Common.Types;
|
||||||
|
using Luban.Job.Common.TypeVisitors;
|
||||||
|
|
||||||
|
namespace Luban.Job.Cfg.TypeVisitors
|
||||||
|
{
|
||||||
|
class RustJsonUnderingConstructorVisitor : ITypeFuncVisitor<string, string>
|
||||||
|
{
|
||||||
|
public static RustJsonUnderingConstructorVisitor Ins { get; } = new();
|
||||||
|
|
||||||
|
private static string AsType(string jsonVarName, string rawType)
|
||||||
|
{
|
||||||
|
return $"match {jsonVarName}.as_{rawType}() {{ Some(__x__) => __x__, None => return Err(LoadError{{}}) }}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TBool type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "bool");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TByte type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "u8");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TShort type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "i16");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TFshort type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "i16");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TInt type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "i32");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TFint type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "i32");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TLong type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "i64");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TFlong type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "i64");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TFloat type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "f32");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TDouble type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "f64");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TEnum type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "i32");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TString type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return $"match {jsonVarName}.as_str() {{ Some(__x__) => __x__.to_string(), None => return Err(LoadError{{}}) }}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TBytes type, string jsonVarName)
|
||||||
|
{
|
||||||
|
throw new System.NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TText type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return $"{{ if !{jsonVarName}[\"{DText.KEY_NAME}\"].is_string() {{ return Err(LoadError{{}}); }} match {jsonVarName}[\"{DText.TEXT_NAME}\"].as_str() {{ Some(__x__) => __x__.to_string(), None => return Err(LoadError{{}}) }} }}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TBean type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return $"{type.Bean.RustFullName}::new(&{jsonVarName})?";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TArray type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return $"{{ if !{jsonVarName}.is_array() {{ return Err(LoadError{{}}); }} let mut __list__ = vec![]; for __e in {jsonVarName}.members() {{ __list__.push({type.ElementType.Apply(this, "__e")}); }} __list__}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TList type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return $"{{ if !{jsonVarName}.is_array() {{ return Err(LoadError{{}}); }} let mut __list__ = vec![]; for __e in {jsonVarName}.members() {{ __list__.push({type.ElementType.Apply(this, "__e")}); }} __list__}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TSet type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return $"{{ if !{jsonVarName}.is_array() {{ return Err(LoadError{{}}); }} let mut __set__ = std::collections::HashSet::new(); for __e in {jsonVarName}.members() {{ __set__.insert({type.ElementType.Apply(this, "__e")}); }} __set__}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TMap type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return $"{{ if !{jsonVarName}.is_array() {{ return Err(LoadError{{}}); }} let mut __map__ = std::collections::HashMap::new(); for __e in {jsonVarName}.members() {{ __map__.insert({type.KeyType.Apply(this, "__e[0]")}, {type.ValueType.Apply(this, "__e[1]")}); }} __map__}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TVector2 type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return $"Vector2::new(&{jsonVarName})?";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TVector3 type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return $"Vector3::new(&{jsonVarName})?";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TVector4 type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return $"Vector4::new(&{jsonVarName})?";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TDateTime type, string jsonVarName)
|
||||||
|
{
|
||||||
|
return AsType(jsonVarName, "i32");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -217,6 +217,11 @@ namespace Luban.Job.Cfg.Utils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string RustJsonConstructor(string jsonFieldName, TType type)
|
||||||
|
{
|
||||||
|
return type.Apply(RustJsonConstructorVisitor.Ins, jsonFieldName);
|
||||||
|
}
|
||||||
|
|
||||||
//public static string DeserializeTextKeyField(DefField field, string lan, string bufName)
|
//public static string DeserializeTextKeyField(DefField field, string lan, string bufName)
|
||||||
//{
|
//{
|
||||||
// switch (lan)
|
// switch (lan)
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ namespace Luban.Job.Common.Defs
|
||||||
|
|
||||||
public string GoStyleName => CsStyleName;
|
public string GoStyleName => CsStyleName;
|
||||||
|
|
||||||
|
public string RustStyleName => Name != "type" ? Name : "r#" + Name;
|
||||||
|
|
||||||
//public string GoStyleAssignName => CType.IsNullable ? "*" + CsStyleName : CsStyleName;
|
//public string GoStyleAssignName => CType.IsNullable ? "*" + CsStyleName : CsStyleName;
|
||||||
|
|
||||||
public string Type { get; }
|
public string Type { get; }
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ namespace Luban.Job.Common.Defs
|
||||||
|
|
||||||
public string PyFullName => TypeUtil.MakePyFullName(Namespace, Name);
|
public string PyFullName => TypeUtil.MakePyFullName(Namespace, Name);
|
||||||
|
|
||||||
|
public string RustFullName => TypeUtil.MakeRustFullName(Namespace, Name);
|
||||||
|
|
||||||
public string Comment { get; protected set; }
|
public string Comment { get; protected set; }
|
||||||
|
|
||||||
public Dictionary<string, string> Tags { get; protected set; }
|
public Dictionary<string, string> Tags { get; protected set; }
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,23 @@ namespace Luban.Job.Common.Defs
|
||||||
return type.Apply(LuaConstValueVisitor.Ins, value);
|
return type.Apply(LuaConstValueVisitor.Ins, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string RustClassName(TBean type)
|
||||||
|
{
|
||||||
|
return type.Bean.RustFullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string RustDefineType(TType type)
|
||||||
|
{
|
||||||
|
return type.Apply(RustTypeNameVisitor.Ins);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string RustConstValue(TType type, string value)
|
||||||
|
{
|
||||||
|
return type.Apply(LuaConstValueVisitor.Ins, value);
|
||||||
|
}
|
||||||
|
|
||||||
public static bool HasTag(dynamic obj, string attrName)
|
public static bool HasTag(dynamic obj, string attrName)
|
||||||
{
|
{
|
||||||
return obj.HasTag(attrName);
|
return obj.HasTag(attrName);
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,6 @@ namespace Luban.Job.Common
|
||||||
TYPESCRIPT,
|
TYPESCRIPT,
|
||||||
PYTHON,
|
PYTHON,
|
||||||
ERLANG,
|
ERLANG,
|
||||||
|
RUST,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
using Luban.Job.Common.Types;
|
||||||
|
|
||||||
|
namespace Luban.Job.Common.TypeVisitors
|
||||||
|
{
|
||||||
|
public class RustTypeNameVisitor : DecoratorFuncVisitor<string>
|
||||||
|
{
|
||||||
|
public static RustTypeNameVisitor Ins { get; } = new();
|
||||||
|
|
||||||
|
public override string DoAccept(TType type)
|
||||||
|
{
|
||||||
|
if (type.IsNullable)
|
||||||
|
{
|
||||||
|
if (type.IsBean)
|
||||||
|
{
|
||||||
|
return $"std::option::Option<std::rc::Rc<{type.Apply(RustTypeUnderlyingNameVisitor.Ins)}>>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $"std::option::Option<{type.Apply(RustTypeUnderlyingNameVisitor.Ins)}>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (type.IsBean)
|
||||||
|
{
|
||||||
|
return $"std::rc::Rc<{type.Apply(RustTypeUnderlyingNameVisitor.Ins)}>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return type.Apply(RustTypeUnderlyingNameVisitor.Ins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
using Luban.Job.Common.Types;
|
||||||
|
|
||||||
|
namespace Luban.Job.Common.TypeVisitors
|
||||||
|
{
|
||||||
|
public class RustTypeUnderlyingNameVisitor : ITypeFuncVisitor<string>
|
||||||
|
{
|
||||||
|
public static RustTypeUnderlyingNameVisitor Ins { get; } = new();
|
||||||
|
|
||||||
|
public string Accept(TBool type)
|
||||||
|
{
|
||||||
|
return "bool";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TByte type)
|
||||||
|
{
|
||||||
|
return "u8";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TShort type)
|
||||||
|
{
|
||||||
|
return "i16";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TFshort type)
|
||||||
|
{
|
||||||
|
return "i16";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TInt type)
|
||||||
|
{
|
||||||
|
return "i32";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TFint type)
|
||||||
|
{
|
||||||
|
return "i32";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TLong type)
|
||||||
|
{
|
||||||
|
return "i64";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TFlong type)
|
||||||
|
{
|
||||||
|
return "i64";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TFloat type)
|
||||||
|
{
|
||||||
|
return "f32";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TDouble type)
|
||||||
|
{
|
||||||
|
return "f64";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TEnum type)
|
||||||
|
{
|
||||||
|
return "i32";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TString type)
|
||||||
|
{
|
||||||
|
return "String";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TBytes type)
|
||||||
|
{
|
||||||
|
throw new System.NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TText type)
|
||||||
|
{
|
||||||
|
return "String";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TBean type)
|
||||||
|
{
|
||||||
|
return type.Bean.RustFullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TArray type)
|
||||||
|
{
|
||||||
|
return $"Vec<{type.ElementType.Apply(RustTypeNameVisitor.Ins)}>";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TList type)
|
||||||
|
{
|
||||||
|
return $"Vec<{type.ElementType.Apply(RustTypeNameVisitor.Ins)}>";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TSet type)
|
||||||
|
{
|
||||||
|
return $"std::collections::HashSet<{type.ElementType.Apply(RustTypeNameVisitor.Ins)}>";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TMap type)
|
||||||
|
{
|
||||||
|
return $"std::collections::HashMap<{type.KeyType.Apply(RustTypeNameVisitor.Ins)}, {type.ValueType.Apply(RustTypeNameVisitor.Ins)}>";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TVector2 type)
|
||||||
|
{
|
||||||
|
return "Vector2";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TVector3 type)
|
||||||
|
{
|
||||||
|
return "Vector3";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TVector4 type)
|
||||||
|
{
|
||||||
|
return "Vector4";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Accept(TDateTime type)
|
||||||
|
{
|
||||||
|
return "i32";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@ namespace Luban.Job.Common.Utils
|
||||||
case ELanguage.LUA: return fullName.Replace('.', '_') + ".lua";
|
case ELanguage.LUA: return fullName.Replace('.', '_') + ".lua";
|
||||||
case ELanguage.JS: return fullName + ".js";
|
case ELanguage.JS: return fullName + ".js";
|
||||||
case ELanguage.TYPESCRIPT: return fullName.Replace('.', '/') + ".ts";
|
case ELanguage.TYPESCRIPT: return fullName.Replace('.', '/') + ".ts";
|
||||||
|
case ELanguage.RUST: return fullName.Replace('.', '_') + ".rs";
|
||||||
default: throw new NotSupportedException();
|
default: throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,6 +98,7 @@ namespace Luban.Job.Common.Utils
|
||||||
{ "typescript", ELanguage.TYPESCRIPT },
|
{ "typescript", ELanguage.TYPESCRIPT },
|
||||||
{ "javascript", ELanguage.JS },
|
{ "javascript", ELanguage.JS },
|
||||||
{ "erlang", ELanguage.ERLANG },
|
{ "erlang", ELanguage.ERLANG },
|
||||||
|
{ "rust", ELanguage.RUST },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static ELanguage GetLanguage(string genType)
|
public static ELanguage GetLanguage(string genType)
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,26 @@ namespace Luban.Job.Common.Utils
|
||||||
{
|
{
|
||||||
var template = StringTemplateUtil.GetTemplate("common/typescript/enum");
|
var template = StringTemplateUtil.GetTemplate("common/typescript/enum");
|
||||||
var result = template.Render(e);
|
var result = template.Render(e);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string RenderRustConstClass(DefConst c)
|
||||||
|
{
|
||||||
|
var ctx = new TemplateContext();
|
||||||
|
var env = new TTypeTemplateCommonExtends
|
||||||
|
{
|
||||||
|
["x"] = c
|
||||||
|
};
|
||||||
|
ctx.PushGlobal(env);
|
||||||
|
var template = StringTemplateUtil.GetTemplate("common/rust/const");
|
||||||
|
var result = template.Render(ctx);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string RenderRustEnumClass(DefEnum e)
|
||||||
|
{
|
||||||
|
var template = StringTemplateUtil.GetTemplate("common/rust/enum");
|
||||||
|
var result = template.Render(e);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,12 @@
|
||||||
<None Update="Templates\common\python\enum.tpl">
|
<None Update="Templates\common\python\enum.tpl">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Templates\common\rust\const.tpl">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Templates\common\rust\enum.tpl">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Update="Templates\common\typescript\const.tpl">
|
<None Update="Templates\common\typescript\const.tpl">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -175,6 +181,18 @@
|
||||||
<None Update="Templates\config\python_json\tables.tpl">
|
<None Update="Templates\config\python_json\tables.tpl">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Templates\config\rust_json\bean.tpl">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Templates\config\rust_json\mod_header.tpl">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Templates\config\rust_json\table.tpl">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Templates\config\rust_json\tables.tpl">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Update="Templates\config\typescript_bin\bean.tpl">
|
<None Update="Templates\config\typescript_bin\bean.tpl">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
{{~if x.comment != '' ~}}
|
||||||
|
/**
|
||||||
|
* {{x.comment}}
|
||||||
|
*/
|
||||||
|
{{~end~}}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub mod {{x.rust_full_name}} {
|
||||||
|
{{~ for item in x.items ~}}
|
||||||
|
{{~if item.comment != '' ~}}
|
||||||
|
/**
|
||||||
|
* {{item.comment}}
|
||||||
|
*/
|
||||||
|
{{~end~}}
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const {{string.upcase item.name}}: {{rust_define_type item.ctype}} = {{rust_const_value item.ctype item.value}};
|
||||||
|
{{~end~}}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
{{~if comment != '' ~}}
|
||||||
|
/**
|
||||||
|
* {{comment}}
|
||||||
|
*/
|
||||||
|
{{~end~}}
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub enum {{rust_full_name}} {
|
||||||
|
{{~for item in items ~}}
|
||||||
|
{{~if item.comment != '' ~}}
|
||||||
|
/**
|
||||||
|
* {{item.comment}}
|
||||||
|
*/
|
||||||
|
{{~end~}}
|
||||||
|
{{item.name}} = {{item.int_value}},
|
||||||
|
{{~end~}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
{{
|
||||||
|
name = x.rust_full_name
|
||||||
|
parent_def_type = x.parent_def_type
|
||||||
|
export_fields = x.export_fields
|
||||||
|
hierarchy_export_fields = x.hierarchy_export_fields
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{~if x.comment != '' ~}}
|
||||||
|
/**
|
||||||
|
* {{x.comment}}
|
||||||
|
*/
|
||||||
|
{{~end~}}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct {{name}} {
|
||||||
|
{{~for field in hierarchy_export_fields~}}
|
||||||
|
pub {{field.rust_style_name}}: {{rust_define_type field.ctype}},
|
||||||
|
{{~end~}}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl {{name}} {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn new(__js: &json::JsonValue) -> Result<std::rc::Rc<{{name}}>, LoadError> {
|
||||||
|
let __b = {{name}} {
|
||||||
|
{{~for field in hierarchy_export_fields~}}
|
||||||
|
{{field.rust_style_name}}: {{rust_json_constructor ('__js["' + field.name + '"]') field.ctype}},
|
||||||
|
{{~end~}}
|
||||||
|
};
|
||||||
|
Ok(std::rc::Rc::new(__b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
pub struct LoadError {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for LoadError {
|
||||||
|
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { Ok(()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct Vector2 {
|
||||||
|
pub x:f32,
|
||||||
|
pub y:f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vector2 {
|
||||||
|
pub fn new(__js:&json::JsonValue) -> Result<Vector2, LoadError> {
|
||||||
|
Ok(Vector2{
|
||||||
|
x: match __js["x"].as_f32() { Some(__x__) => __x__, None => return Err(LoadError{})},
|
||||||
|
y: match __js["y"].as_f32() { Some(__x__) => __x__, None => return Err(LoadError{})},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct Vector3 {
|
||||||
|
pub x:f32,
|
||||||
|
pub y:f32,
|
||||||
|
pub z:f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vector3 {
|
||||||
|
pub fn new(__js:&json::JsonValue) -> Result<Vector3, LoadError> {
|
||||||
|
Ok(Vector3{
|
||||||
|
x: match __js["x"].as_f32() { Some(__x__) => __x__, None => return Err(LoadError{})},
|
||||||
|
y: match __js["y"].as_f32() { Some(__x__) => __x__, None => return Err(LoadError{})},
|
||||||
|
z: match __js["z"].as_f32() { Some(__x__) => __x__, None => return Err(LoadError{})},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct Vector4 {
|
||||||
|
pub x:f32,
|
||||||
|
pub y:f32,
|
||||||
|
pub z:f32,
|
||||||
|
pub w:f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Vector4 {
|
||||||
|
pub fn new(__js:&json::JsonValue) -> Result<Vector4, LoadError> {
|
||||||
|
Ok(Vector4{
|
||||||
|
x: match __js["x"].as_f32() { Some(__x__) => __x__, None => return Err(LoadError{})},
|
||||||
|
y: match __js["y"].as_f32() { Some(__x__) => __x__, None => return Err(LoadError{})},
|
||||||
|
z: match __js["z"].as_f32() { Some(__x__) => __x__, None => return Err(LoadError{})},
|
||||||
|
w: match __js["w"].as_f32() { Some(__x__) => __x__, None => return Err(LoadError{})},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
{{
|
||||||
|
name = x.rust_full_name
|
||||||
|
key_type = x.key_ttype
|
||||||
|
value_type = x.value_ttype
|
||||||
|
}}
|
||||||
|
{{~if x.comment != '' ~}}
|
||||||
|
/**
|
||||||
|
* {{x.comment}}
|
||||||
|
*/
|
||||||
|
{{~end~}}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct {{name}} {
|
||||||
|
{{~if x.is_map_table ~}}
|
||||||
|
data_list: Vec<{{rust_define_type value_type}}>,
|
||||||
|
data_map: std::collections::HashMap<{{rust_define_type key_type}}, {{rust_define_type value_type}}>,
|
||||||
|
{{~else~}}
|
||||||
|
data: {{rust_define_type value_type}},
|
||||||
|
{{~end~}}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl {{name}}{
|
||||||
|
pub fn new(__js: &json::JsonValue) -> Result<std::rc::Rc<{{name}}>, LoadError> {
|
||||||
|
{{~if x.is_map_table ~}}
|
||||||
|
if !__js.is_array() {
|
||||||
|
return Err(LoadError{});
|
||||||
|
}
|
||||||
|
let mut t = {{name}} {
|
||||||
|
data_list : Vec::new(),
|
||||||
|
data_map: std::collections::HashMap::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
for __e in __js.members() {
|
||||||
|
let __v = match {{rust_class_name value_type}}::new(__e) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
};
|
||||||
|
let __v2 = std::rc::Rc::clone(&__v);
|
||||||
|
t.data_list.push(__v);
|
||||||
|
t.data_map.insert(__v2.{{x.index_field.rust_style_name}}.clone(), __v2);
|
||||||
|
}
|
||||||
|
Ok(std::rc::Rc::new(t))
|
||||||
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn get_data_map(self:&{{name}}) -> &std::collections::HashMap<{{rust_define_type key_type}}, {{rust_define_type value_type}}> { &self.data_map }
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn get_data_list(self:&{{name}}) -> &Vec<{{rust_define_type value_type}}> { &self.data_list }
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn get(self:&{{name}}, key: {{rust_define_type key_type}}) -> std::option::Option<&{{rust_define_type value_type}}> { self.data_map.get(&key) }
|
||||||
|
{{~else~}}
|
||||||
|
if !__js.is_array() || __js.len() != 1 {
|
||||||
|
return Err(LoadError{});
|
||||||
|
}
|
||||||
|
let __v = match {{rust_class_name value_type}}::new(&__js[0]) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
};
|
||||||
|
let t = {{name}} {
|
||||||
|
data: __v,
|
||||||
|
};
|
||||||
|
Ok(std::rc::Rc::new(t))
|
||||||
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn get_data(self:&{{name}}) -> &{{rust_define_type value_type}} { &self.data }
|
||||||
|
{{~end~}}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
{{
|
||||||
|
name = x.name
|
||||||
|
namespace = x.namespace
|
||||||
|
tables = x.tables
|
||||||
|
}}
|
||||||
|
|
||||||
|
type JsonLoader = fn(&str) -> Result<json::JsonValue, LoadError>;
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct {{name}} {
|
||||||
|
{{~ for table in tables ~}}
|
||||||
|
|
||||||
|
{{~if table.comment != '' ~}}
|
||||||
|
/**
|
||||||
|
* {{table.comment}}
|
||||||
|
*/
|
||||||
|
{{~end~}}
|
||||||
|
pub {{string.downcase table.name}}: std::rc::Rc<{{table.rust_full_name}}>,
|
||||||
|
{{~end~}}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl {{name}} {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn new(loader: JsonLoader) -> std::result::Result<std::rc::Rc<Tables>, LoadError> {
|
||||||
|
let tables = Tables {
|
||||||
|
{{~for table in tables ~}}
|
||||||
|
{{string.downcase table.name}}: {{table.rust_full_name}}::new(&loader("{{table.output_data_file}}")?)?,
|
||||||
|
{{~end~}}
|
||||||
|
};
|
||||||
|
return Ok(std::rc::Rc::new(tables));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue