mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-08-18 04:28:40 +00:00
feat[rust]: rust protocol generation
This commit is contained in:
@@ -82,6 +82,7 @@ public abstract class GenerateProtocolNote {
|
||||
private static String formatNote(CodeLanguage language, String note) {
|
||||
switch (language) {
|
||||
case Cpp:
|
||||
case Rust:
|
||||
case Java:
|
||||
case Kotlin:
|
||||
case Scala:
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.zfoo.protocol.serializer.kotlin.CodeGenerateKotlin;
|
||||
import com.zfoo.protocol.serializer.lua.CodeGenerateLua;
|
||||
import com.zfoo.protocol.serializer.php.CodeGeneratePhp;
|
||||
import com.zfoo.protocol.serializer.python.CodeGeneratePython;
|
||||
import com.zfoo.protocol.serializer.rust.CodeGenerateRust;
|
||||
import com.zfoo.protocol.serializer.scala.CodeGenerateScala;
|
||||
import com.zfoo.protocol.serializer.typescript.CodeGenerateTypeScript;
|
||||
|
||||
@@ -44,6 +45,8 @@ public enum CodeLanguage {
|
||||
|
||||
Cpp(1 << 7, CodeGenerateCpp.class),
|
||||
|
||||
Rust(1 << 8, CodeGenerateRust.class),
|
||||
|
||||
Golang(1 << 9, CodeGenerateGolang.class),
|
||||
|
||||
JavaScript(1 << 10, CodeGenerateJavaScript.class),
|
||||
|
||||
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.anno.Compatible;
|
||||
import com.zfoo.protocol.generate.GenerateOperation;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolNote;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolPath;
|
||||
import com.zfoo.protocol.registration.ProtocolAnalysis;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.serializer.CodeLanguage;
|
||||
import com.zfoo.protocol.serializer.CodeTemplatePlaceholder;
|
||||
import com.zfoo.protocol.serializer.ICodeGenerate;
|
||||
import com.zfoo.protocol.serializer.enhance.EnhanceObjectProtocolSerializer;
|
||||
import com.zfoo.protocol.serializer.reflect.*;
|
||||
import com.zfoo.protocol.util.ClassUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
import static com.zfoo.protocol.util.StringUtils.TAB;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class CodeGenerateRust implements ICodeGenerate {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CodeGenerateRust.class);
|
||||
|
||||
// custom configuration
|
||||
public static String protocolOutputRootPath = "zfoorust";
|
||||
private static String protocolOutputPath = StringUtils.EMPTY;
|
||||
|
||||
private static final Map<ISerializer, IRustSerializer> rustSerializerMap = new HashMap<>();
|
||||
|
||||
public static IRustSerializer rustSerializer(ISerializer serializer) {
|
||||
return rustSerializerMap.get(serializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(GenerateOperation generateOperation) {
|
||||
protocolOutputPath = FileUtils.joinPath(generateOperation.getProtocolPath(), protocolOutputRootPath);
|
||||
FileUtils.deleteFile(new File(protocolOutputPath));
|
||||
|
||||
rustSerializerMap.put(BoolSerializer.INSTANCE, new RustBoolSerializer());
|
||||
rustSerializerMap.put(ByteSerializer.INSTANCE, new RustByteSerializer());
|
||||
rustSerializerMap.put(ShortSerializer.INSTANCE, new RustShortSerializer());
|
||||
rustSerializerMap.put(IntSerializer.INSTANCE, new RustIntSerializer());
|
||||
rustSerializerMap.put(LongSerializer.INSTANCE, new RustLongSerializer());
|
||||
rustSerializerMap.put(FloatSerializer.INSTANCE, new RustFloatSerializer());
|
||||
rustSerializerMap.put(DoubleSerializer.INSTANCE, new RustDoubleSerializer());
|
||||
rustSerializerMap.put(StringSerializer.INSTANCE, new RustStringSerializer());
|
||||
rustSerializerMap.put(ArraySerializer.INSTANCE, new RustArraySerializer());
|
||||
rustSerializerMap.put(ListSerializer.INSTANCE, new RustListSerializer());
|
||||
rustSerializerMap.put(SetSerializer.INSTANCE, new RustSetSerializer());
|
||||
rustSerializerMap.put(MapSerializer.INSTANCE, new RustMapSerializer());
|
||||
rustSerializerMap.put(ObjectProtocolSerializer.INSTANCE, new RustObjectProtocolSerializer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergerProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile();
|
||||
|
||||
|
||||
// 生成ProtocolManager.ts文件
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolManagerTemplate.ts");
|
||||
var protocol_imports_manager = new StringBuilder();
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
protocol_imports_manager.append("import * as Protocols from './Protocols';").append(LS);
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols.set({}, new Protocols.{}Registration());", protocol_id, protocol_name)).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("protocolIdMap.set(Protocols.{}, {});", protocol_name, protocol_id)).append(LS);
|
||||
}
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports_manager.toString()
|
||||
, CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString());
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "ProtocolManager.ts"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated TypeScript protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
|
||||
|
||||
var protocol_imports_protocols = new StringBuilder();
|
||||
protocol_imports_protocols.append("import IByteBuffer from './IByteBuffer';").append(LS);
|
||||
var protocol_class = new StringBuilder();
|
||||
var protocol_registration = new StringBuilder();
|
||||
for (var registration : registrations) {
|
||||
protocol_class.append(protocol_class(registration).replace("class ", "export class ")).append(LS);
|
||||
protocol_registration.append(protocol_registration(registration)).append(LS);
|
||||
}
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolsTemplate.ts");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_imports, protocol_imports_protocols.toString()
|
||||
, CodeTemplatePlaceholder.protocol_class, protocol_class.toString()
|
||||
, CodeTemplatePlaceholder.protocol_registration, protocol_registration.toString()
|
||||
));
|
||||
var outputPath = StringUtils.format("{}/Protocols.ts", protocolOutputPath);
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated TypeScript protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void foldProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile();
|
||||
|
||||
|
||||
// 生成ProtocolManager.ts文件
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolManagerTemplate.ts");
|
||||
var protocol_imports = new StringBuilder();
|
||||
var protocol_manager_registrations = new StringBuilder();
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_imports.append(StringUtils.format("import {} from './{}/{}';", protocol_name, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name)).append(LS);
|
||||
protocol_imports.append(StringUtils.format("import { {}Registration } from './{}/{}';", protocol_name, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name)).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("protocols.set({}, new {}Registration());", protocol_id, protocol_name)).append(LS);
|
||||
protocol_manager_registrations.append(StringUtils.format("protocolIdMap.set({}, {});", protocol_name, protocol_id)).append(LS);
|
||||
}
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString()
|
||||
, CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString());
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "ProtocolManager.ts"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated TypeScript protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
|
||||
//
|
||||
// for (var registration : registrations) {
|
||||
// var protocol_id = registration.protocolId();
|
||||
// var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
// var protocolTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolTemplate.ts");
|
||||
// var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
// CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
// , CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
// , CodeTemplatePlaceholder.protocol_imports, protocol_imports_fold(registration)
|
||||
// , CodeTemplatePlaceholder.protocol_class, protocol_class(registration)
|
||||
// , CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration)
|
||||
// ));
|
||||
// var outputPath = StringUtils.format("{}/{}/{}.ts", protocolOutputPath, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name);
|
||||
// var file = new File(outputPath);
|
||||
// FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
// logger.info("Generated TypeScript protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defaultProtocol(List<ProtocolRegistration> registrations) throws IOException {
|
||||
createTemplateFile();
|
||||
|
||||
|
||||
// 生成mod文件
|
||||
var modBuilder = new StringBuilder();
|
||||
modBuilder.append("pub mod i_byte_buffer;").append(LS);
|
||||
modBuilder.append("pub mod byte_buffer;").append(LS);
|
||||
modBuilder.append("pub mod protocol_manager;").append(LS);
|
||||
for (var registration : registrations) {
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
modBuilder.append(StringUtils.format("pub mod {};", StringUtils.uncapitalize(protocol_name))).append(LS);
|
||||
}
|
||||
var modFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "mod.rs"));
|
||||
FileUtils.writeStringToFile(modFile, modBuilder.toString(), true);
|
||||
logger.info("Generated Rust mod file:[{}] is in path:[{}]", modFile.getName(), modFile.getAbsolutePath());
|
||||
|
||||
|
||||
// 生成ProtocolManager.ts文件
|
||||
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("rust/protocol_manager_template.rs");
|
||||
var protocol_imports = new StringBuilder();
|
||||
var protocol_manager_write_registrations = new StringBuilder();
|
||||
var protocol_manager_read_registrations = new StringBuilder();
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
protocol_imports.append(StringUtils.format("use crate::{}::{}::{{}, write{}, read{}};", protocolOutputRootPath, StringUtils.uncapitalize(protocol_name), protocol_name, protocol_name, protocol_name)).append(LS);
|
||||
protocol_manager_write_registrations.append(StringUtils.format("{} => write{}(buffer, packet),", protocol_id, protocol_name)).append(LS);
|
||||
protocol_manager_read_registrations.append(StringUtils.format("{} => read{}(buffer),", protocol_id, protocol_name)).append(LS);
|
||||
}
|
||||
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_root_path, protocolOutputRootPath
|
||||
, CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString()
|
||||
, CodeTemplatePlaceholder.protocol_write_serialization, protocol_manager_write_registrations.toString()
|
||||
, CodeTemplatePlaceholder.protocol_read_deserialization, protocol_manager_read_registrations.toString()
|
||||
);
|
||||
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
|
||||
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "protocol_manager.rs"));
|
||||
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
|
||||
logger.info("Generated Rust protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
|
||||
|
||||
|
||||
for (var registration : registrations) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("rust/protocol_template.rs");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_root_path, protocolOutputRootPath
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_imports, protocol_imports_default(registration)
|
||||
, CodeTemplatePlaceholder.protocol_class, protocol_class(registration)
|
||||
, CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration)
|
||||
));
|
||||
var outputPath = StringUtils.format("{}/{}.rs", protocolOutputPath, StringUtils.uncapitalize(protocol_name));
|
||||
var file = new File(outputPath);
|
||||
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
|
||||
logger.info("Generated Rust protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private void createTemplateFile() throws IOException {
|
||||
var list = List.of("rust/byte_buffer.rs", "rust/i_byte_buffer.rs");
|
||||
for (var fileName : list) {
|
||||
var template = ClassUtils.getFileFromClassPathToString(fileName);
|
||||
var formatTemplate = CodeTemplatePlaceholder.formatTemplate(template, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_root_path, protocolOutputRootPath
|
||||
));
|
||||
var createFile = new File(StringUtils.format("{}/{}", protocolOutputPath, StringUtils.substringAfterFirst(fileName, "rust/")));
|
||||
FileUtils.writeStringToFile(createFile, formatTemplate, false);
|
||||
}
|
||||
}
|
||||
|
||||
private String protocol_class(ProtocolRegistration registration) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("rust/protocol_class_template.rs");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.Rust)
|
||||
, CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration)
|
||||
));
|
||||
return formatProtocolTemplate;
|
||||
}
|
||||
|
||||
private String protocol_registration(ProtocolRegistration registration) {
|
||||
var protocol_id = registration.protocolId();
|
||||
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var protocolTemplate = ClassUtils.getFileFromClassPathToString("rust/protocol_registration_template.rs");
|
||||
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
|
||||
CodeTemplatePlaceholder.protocol_name, protocol_name
|
||||
, CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
|
||||
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition_new(registration)
|
||||
, CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration)
|
||||
, CodeTemplatePlaceholder.protocol_read_deserialization, protocol_read_deserialization(registration)
|
||||
));
|
||||
return formatProtocolTemplate;
|
||||
}
|
||||
|
||||
private String protocol_imports_default(ProtocolRegistration registration) {
|
||||
// import IByteBuffer first
|
||||
var protocolId = registration.getId();
|
||||
var importBuilder = new StringBuilder();
|
||||
// import other sub protocols
|
||||
var subProtocols = ProtocolAnalysis.getFirstSubProtocolIds(protocolId);
|
||||
for (var subProtocolId : subProtocols) {
|
||||
var protocolName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
|
||||
importBuilder.append(StringUtils.format("use crate::{}::{}::{};", protocolOutputRootPath, StringUtils.uncapitalize(protocolName), protocolName)).append(LS);
|
||||
}
|
||||
return importBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_field_definition(ProtocolRegistration registration) {
|
||||
var protocolId = registration.protocolId();
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
// when generate source code fields, use origin fields sort
|
||||
var sequencedFields = ReflectionUtils.notStaticAndTransientFields(registration.getConstructor().getDeclaringClass());
|
||||
var rustBuilder = new StringBuilder();
|
||||
for (var field : sequencedFields) {
|
||||
var fieldRegistration = fieldRegistrations[GenerateProtocolFile.indexOf(fields, field)];
|
||||
var fieldName = field.getName();
|
||||
// 生成注释
|
||||
var fieldNotes = GenerateProtocolNote.fieldNotes(protocolId, fieldName, CodeLanguage.Rust);
|
||||
for (var fieldNote : fieldNotes) {
|
||||
rustBuilder.append(fieldNote).append(LS);
|
||||
}
|
||||
var fieldTypeDefaultValue = rustSerializer(fieldRegistration.serializer()).fieldTypeDefaultValue(field, fieldRegistration);
|
||||
var fieldType = fieldTypeDefaultValue.getKey();
|
||||
var fieldDefaultValue = fieldTypeDefaultValue.getValue();
|
||||
rustBuilder.append(StringUtils.format("pub {}: {},", fieldName, fieldType)).append(LS);
|
||||
}
|
||||
return rustBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_field_definition_new(ProtocolRegistration registration) {
|
||||
var protocolId = registration.protocolId();
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
// when generate source code fields, use origin fields sort
|
||||
var sequencedFields = ReflectionUtils.notStaticAndTransientFields(registration.getConstructor().getDeclaringClass());
|
||||
var rustBuilder = new StringBuilder();
|
||||
for (var field : sequencedFields) {
|
||||
var fieldRegistration = fieldRegistrations[GenerateProtocolFile.indexOf(fields, field)];
|
||||
var fieldName = field.getName();
|
||||
// 生成注释
|
||||
var fieldNotes = GenerateProtocolNote.fieldNotes(protocolId, fieldName, CodeLanguage.Rust);
|
||||
for (var fieldNote : fieldNotes) {
|
||||
rustBuilder.append(fieldNote).append(LS);
|
||||
}
|
||||
var fieldTypeDefaultValue = rustSerializer(fieldRegistration.serializer()).fieldTypeDefaultValue(field, fieldRegistration);
|
||||
var fieldType = fieldTypeDefaultValue.getKey();
|
||||
var fieldDefaultValue = fieldTypeDefaultValue.getValue();
|
||||
rustBuilder.append(StringUtils.format("{}: {},", fieldName, fieldDefaultValue)).append(LS);
|
||||
}
|
||||
return rustBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_write_serialization(ProtocolRegistration registration) {
|
||||
GenerateProtocolFile.localVariableId = 0;
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var rustBuilder = new StringBuilder();
|
||||
if (registration.isCompatible()) {
|
||||
rustBuilder.append("let beforeWriteIndex = buffer.getWriteOffset();").append(LS);
|
||||
rustBuilder.append(StringUtils.format("buffer.writeInt({});", registration.getPredictionLength())).append(LS);
|
||||
} else {
|
||||
rustBuilder.append("buffer.writeInt(-1);").append(LS);
|
||||
}
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
var serializer = rustSerializer(fieldRegistration.serializer());
|
||||
if (serializer instanceof RustStringSerializer || serializer instanceof RustObjectProtocolSerializer) {
|
||||
serializer.writeObject(rustBuilder, "&message." + field.getName(), 0, field, fieldRegistration);
|
||||
} else {
|
||||
serializer.writeObject(rustBuilder, "message." + field.getName(), 0, field, fieldRegistration);
|
||||
}
|
||||
}
|
||||
if (registration.isCompatible()) {
|
||||
rustBuilder.append(StringUtils.format("buffer.adjustPadding({}, beforeWriteIndex);", registration.getPredictionLength())).append(LS);
|
||||
}
|
||||
return rustBuilder.toString();
|
||||
}
|
||||
|
||||
private String protocol_read_deserialization(ProtocolRegistration registration) {
|
||||
GenerateProtocolFile.localVariableId = 0;
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var rustBuilder = new StringBuilder();
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
if (field.isAnnotationPresent(Compatible.class)) {
|
||||
rustBuilder.append("if (buffer.compatibleRead(beforeReadIndex, length)) {").append(LS);
|
||||
var compatibleReadObject = rustSerializer(fieldRegistration.serializer()).readObject(rustBuilder, 1, field, fieldRegistration);
|
||||
rustBuilder.append(TAB).append(StringUtils.format("packet.{} = {};", field.getName(), compatibleReadObject)).append(LS);
|
||||
rustBuilder.append("}").append(LS);
|
||||
continue;
|
||||
}
|
||||
var readObject = rustSerializer(fieldRegistration.serializer()).readObject(rustBuilder, 0, field, fieldRegistration);
|
||||
rustBuilder.append(StringUtils.format("packet.{} = {};", field.getName(), readObject)).append(LS);
|
||||
}
|
||||
return rustBuilder.toString();
|
||||
}
|
||||
|
||||
public static String toRustClassName(String typeName) {
|
||||
typeName = typeName.replaceAll("java.util.|java.lang.", StringUtils.EMPTY);
|
||||
typeName = typeName.replaceAll("[a-zA-Z0-9_.]*\\.", StringUtils.EMPTY);
|
||||
|
||||
// CSharp不适用基础类型的泛型,会影响性能
|
||||
switch (typeName) {
|
||||
case "boolean":
|
||||
case "Boolean":
|
||||
typeName = "bool";
|
||||
return typeName;
|
||||
case "byte":
|
||||
case "Byte":
|
||||
typeName = "i8";
|
||||
return typeName;
|
||||
case "short":
|
||||
case "Short":
|
||||
typeName = "i16";
|
||||
return typeName;
|
||||
case "int":
|
||||
case "Integer":
|
||||
typeName = "i32";
|
||||
return typeName;
|
||||
case "long":
|
||||
case "Long":
|
||||
typeName = "i64";
|
||||
return typeName;
|
||||
case "Float":
|
||||
typeName = "f32";
|
||||
return typeName;
|
||||
case "Double":
|
||||
typeName = "f64";
|
||||
return typeName;
|
||||
case "String":
|
||||
typeName = "String";
|
||||
return typeName;
|
||||
default:
|
||||
}
|
||||
|
||||
// 将boolean转为bool
|
||||
typeName = typeName.replaceAll("[B|b]oolean\\[", "bool");
|
||||
typeName = typeName.replace("<Boolean", "<bool");
|
||||
typeName = typeName.replace("Boolean>", "bool>");
|
||||
|
||||
// 将Byte转为byte
|
||||
typeName = typeName.replace("Byte[", "i8");
|
||||
typeName = typeName.replace("Byte>", "i8>");
|
||||
typeName = typeName.replace("<Byte", "<i8");
|
||||
|
||||
// 将Short转为short
|
||||
typeName = typeName.replace("Short[", "i16");
|
||||
typeName = typeName.replace("Short>", "i16>");
|
||||
typeName = typeName.replace("<Short", "<i16");
|
||||
|
||||
// 将Integer转为int
|
||||
typeName = typeName.replace("Integer[", "i32");
|
||||
typeName = typeName.replace("Integer>", "i32>");
|
||||
typeName = typeName.replace("<Integer", "<i32");
|
||||
|
||||
|
||||
// 将Long转为long
|
||||
typeName = typeName.replace("Long[", "i64");
|
||||
typeName = typeName.replace("Long>", "i64>");
|
||||
typeName = typeName.replace("<Long", "<i64");
|
||||
|
||||
// 将Float转为float
|
||||
typeName = typeName.replace("Float[", "f32");
|
||||
typeName = typeName.replace("Float>", "f32>");
|
||||
typeName = typeName.replace("<Float", "<f32");
|
||||
|
||||
// 将Double转为double
|
||||
typeName = typeName.replace("Double[", "f64");
|
||||
typeName = typeName.replace("Double>", "f64>");
|
||||
typeName = typeName.replace("<Double", "<f64");
|
||||
|
||||
// 将String转为string
|
||||
typeName = typeName.replace("String[", "String");
|
||||
typeName = typeName.replace("String>", "String>");
|
||||
typeName = typeName.replace("<String", "<String");
|
||||
|
||||
// 将Map转为map
|
||||
typeName = typeName.replace("Map<", "HashMap<");
|
||||
|
||||
// 将Set转为set
|
||||
typeName = typeName.replace("Set<", "HashSet<");
|
||||
|
||||
// 将List转为vector
|
||||
typeName = typeName.replace("List<", "Vec<");
|
||||
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public interface IRustSerializer {
|
||||
|
||||
/**
|
||||
* 获取属性的类型,默认值
|
||||
*/
|
||||
Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.ArrayField;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.CodeLanguage;
|
||||
import com.zfoo.protocol.serializer.CutDownArraySerializer;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustArraySerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
var type = StringUtils.format("Vec<{}>", CodeGenerateRust.toRustClassName(field.getType().getComponentType().getSimpleName()));
|
||||
return new Pair<>(type, "Vec::new()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
if (CutDownArraySerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Rust)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayField arrayField = (ArrayField) fieldRegistration;
|
||||
|
||||
builder.append(StringUtils.format("if ({}.is_empty()) {", objectStr)).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("buffer.writeInt(0);").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
|
||||
builder.append("} else {").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("buffer.writeInt({}.len() as i32);", objectStr)).append(LS);
|
||||
|
||||
String element = "element" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in {} {", element, objectStr)).append(LS);
|
||||
CodeGenerateRust.rustSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
var cutDown = CutDownArraySerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Rust);
|
||||
if (cutDown != null) {
|
||||
return cutDown;
|
||||
}
|
||||
|
||||
ArrayField arrayField = (ArrayField) fieldRegistration;
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
var typeName = StringUtils.format("Vec<{}>", CodeGenerateRust.toRustClassName(arrayField.getType().getSimpleName()));
|
||||
builder.append(StringUtils.format("let mut {}: {} = Vec::new();", result, typeName)).append(LS);
|
||||
|
||||
String i = "index" + GenerateProtocolFile.localVariableId++;
|
||||
String size = "size" + GenerateProtocolFile.localVariableId++;
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = buffer.readInt();", size)).append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in 0 .. {} {", i, size)).append(LS);
|
||||
String readObject = CodeGenerateRust.rustSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.push({});", result, readObject)).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustBoolSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
return new Pair<>("bool", "false");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.writeBool({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = buffer.readBool(); ", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustByteSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
return new Pair<>("i8", "0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.writeByte({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = buffer.readByte();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustDoubleSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
return new Pair<>("f64", "0f64");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.writeDouble({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = buffer.readDouble();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustFloatSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
return new Pair<>("f32", "0f32");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.writeFloat({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = buffer.readFloat();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustIntSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
return new Pair<>("i32", "0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.writeInt({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = buffer.readInt();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ListField;
|
||||
import com.zfoo.protocol.serializer.CodeLanguage;
|
||||
import com.zfoo.protocol.serializer.CutDownListSerializer;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustListSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
var type = StringUtils.format("{}", CodeGenerateRust.toRustClassName(field.getGenericType().toString()));
|
||||
return new Pair<>(type, "Vec::new()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
if (CutDownListSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Rust)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ListField listField = (ListField) fieldRegistration;
|
||||
|
||||
builder.append(StringUtils.format("if ({}.is_empty()) {", objectStr)).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("buffer.writeInt(0);").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
|
||||
builder.append("} else {").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("buffer.writeInt({}.len() as i32);", objectStr)).append(LS);
|
||||
|
||||
String element = "element" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in {} {", element, objectStr)).append(LS);
|
||||
CodeGenerateRust.rustSerializer(listField.getListElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, listField.getListElementRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
var cutDown = CutDownListSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Rust);
|
||||
if (cutDown != null) {
|
||||
return cutDown;
|
||||
}
|
||||
|
||||
ListField listField = (ListField) fieldRegistration;
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
var typeName = CodeGenerateRust.toRustClassName(listField.getType().toString());
|
||||
builder.append(StringUtils.format("let mut {}: {} = Vec::new();", result, typeName)).append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
String size = "size" + GenerateProtocolFile.localVariableId++;
|
||||
builder.append(StringUtils.format("let {} = buffer.readInt();", size)).append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
String i = "index" + GenerateProtocolFile.localVariableId++;
|
||||
builder.append(StringUtils.format("for {} in 0 .. {} {", i, size)).append(LS);
|
||||
String readObject = CodeGenerateRust.rustSerializer(listField.getListElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, listField.getListElementRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.push({});", result, readObject)).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustLongSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
return new Pair<>("i64", "0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.writeLong({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = buffer.readLong();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.MapField;
|
||||
import com.zfoo.protocol.serializer.CodeLanguage;
|
||||
import com.zfoo.protocol.serializer.CutDownMapSerializer;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustMapSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
var type = StringUtils.format("{}", CodeGenerateRust.toRustClassName(field.getGenericType().toString()));
|
||||
return new Pair<>(type, "HashMap::new()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
if (CutDownMapSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Rust)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MapField mapField = (MapField) fieldRegistration;
|
||||
builder.append(StringUtils.format("if ({}.is_empty()) {", objectStr)).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("buffer.writeInt(0);").append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append("} else {").append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("buffer.writeInt({}.len() as i32);", objectStr)).append(LS);
|
||||
|
||||
String key = "key" + GenerateProtocolFile.localVariableId++;
|
||||
String value = "value" + GenerateProtocolFile.localVariableId++;
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for ({}, {}) in {} {", key, value, objectStr)).append(LS);
|
||||
CodeGenerateRust.rustSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
.writeObject(builder, key, deep + 2, field, mapField.getMapKeyRegistration());
|
||||
CodeGenerateRust.rustSerializer(mapField.getMapValueRegistration().serializer())
|
||||
.writeObject(builder, value, deep + 2, field, mapField.getMapValueRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
var cutDown = CutDownMapSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Rust);
|
||||
if (cutDown != null) {
|
||||
return cutDown;
|
||||
}
|
||||
|
||||
MapField mapField = (MapField) fieldRegistration;
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
var typeName = CodeGenerateRust.toRustClassName(mapField.getType().toString());
|
||||
builder.append(StringUtils.format("let mut {}: {} = HashMap::new();", result, typeName)).append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
String size = "size" + GenerateProtocolFile.localVariableId++;
|
||||
builder.append(StringUtils.format("let {} = buffer.readInt();", size)).append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS);
|
||||
|
||||
String i = "index" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in 0 .. {} {", i, size)).append(LS);
|
||||
String keyObject = CodeGenerateRust.rustSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, mapField.getMapKeyRegistration());
|
||||
|
||||
|
||||
String valueObject = CodeGenerateRust.rustSerializer(mapField.getMapValueRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, mapField.getMapValueRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep + 2);
|
||||
|
||||
builder.append(StringUtils.format("{}.insert({}, {});", result, keyObject, valueObject)).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ObjectProtocolField;
|
||||
import com.zfoo.protocol.serializer.enhance.EnhanceObjectProtocolSerializer;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustObjectProtocolSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
var protocolSimpleName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(objectProtocolField.getProtocolId());
|
||||
var defaultValue = StringUtils.format("{}::new()", protocolSimpleName);
|
||||
return new Pair<>(protocolSimpleName, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.writePacket(&{}, {});", objectStr, objectProtocolField.getProtocolId())).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
var result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
String ptr = "result" + GenerateProtocolFile.localVariableId++;
|
||||
var protocolSimpleName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(objectProtocolField.getProtocolId());
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = buffer.readPacket({});", result, objectProtocolField.getProtocolId())).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = {}.downcast_ref::<{}>().unwrap();", ptr, result, protocolSimpleName)).append(LS);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.SetField;
|
||||
import com.zfoo.protocol.serializer.CodeLanguage;
|
||||
import com.zfoo.protocol.serializer.CutDownSetSerializer;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustSetSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
var type = StringUtils.format("{}", CodeGenerateRust.toRustClassName(field.getGenericType().toString()));
|
||||
return new Pair<>(type, "HashSet::new()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
if (CutDownSetSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Rust)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetField setField = (SetField) fieldRegistration;
|
||||
|
||||
builder.append(StringUtils.format("if ({}.is_empty()) {", objectStr)).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("buffer.writeInt(0);").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
|
||||
builder.append("} else {").append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("buffer.writeInt({}.len() as i32);", objectStr)).append(LS);
|
||||
|
||||
String element = "element" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} in {} {", element, objectStr)).append(LS);
|
||||
CodeGenerateRust.rustSerializer(setField.getSetElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, setField.getSetElementRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
var cutDown = CutDownSetSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Rust);
|
||||
if (cutDown != null) {
|
||||
return cutDown;
|
||||
}
|
||||
|
||||
SetField setField = (SetField) fieldRegistration;
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
var typeName = CodeGenerateRust.toRustClassName(setField.getType().toString());
|
||||
builder.append(StringUtils.format("let mut {}: {} = HashSet::new();", result, typeName)).append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
String size = "size" + GenerateProtocolFile.localVariableId++;
|
||||
builder.append(StringUtils.format("let {} = buffer.readInt();", size)).append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS);
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
String i = "index" + GenerateProtocolFile.localVariableId++;
|
||||
builder.append(StringUtils.format("for {} in 0 .. {} {", i, size)).append(LS);
|
||||
String readObject = CodeGenerateRust.rustSerializer(setField.getSetElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, setField.getSetElementRegistration());
|
||||
GenerateProtocolFile.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.insert({});", result, readObject)).append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustShortSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
return new Pair<>("i16", "0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.writeShort({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = buffer.readShort();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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 com.zfoo.protocol.serializer.rust;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class RustStringSerializer implements IRustSerializer {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) {
|
||||
return new Pair<>("String", "String::from(\"\")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.writeString(&{});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateProtocolFile.localVariableId++;
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("let {} = buffer.readString();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,426 @@
|
||||
use std::any::Any;
|
||||
use crate::${protocol_root_path}::i_byte_buffer::IByteBuffer;
|
||||
use crate::${protocol_root_path}::i_byte_buffer::IPacket;
|
||||
use crate::${protocol_root_path}::protocol_manager::write;
|
||||
use crate::${protocol_root_path}::protocol_manager::readByProtocolId;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub struct ByteBuffer {
|
||||
buffer: Vec<i8>,
|
||||
writeOffset: i32,
|
||||
readOffset: i32,
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(unused_parens)]
|
||||
impl ByteBuffer {
|
||||
pub fn new() -> ByteBuffer {
|
||||
let mut buffer = ByteBuffer {
|
||||
buffer: Vec::new(),
|
||||
writeOffset: 0,
|
||||
readOffset: 0,
|
||||
};
|
||||
buffer.buffer.resize(128, 0);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(unused_parens)]
|
||||
impl IByteBuffer for ByteBuffer {
|
||||
fn getBuffer(&self) -> &Vec<i8> {
|
||||
return &self.buffer;
|
||||
}
|
||||
|
||||
fn getWriteOffset(&self) -> i32 {
|
||||
return self.writeOffset;
|
||||
}
|
||||
|
||||
fn setWriteOffset(&mut self, writeIndex: i32) {
|
||||
self.writeOffset = writeIndex;
|
||||
}
|
||||
|
||||
fn getReadOffset(&self) -> i32 {
|
||||
return self.readOffset;
|
||||
}
|
||||
|
||||
fn setReadOffset(&mut self, readIndex: i32) {
|
||||
self.readOffset = readIndex;
|
||||
}
|
||||
|
||||
fn getCapacity(&self) -> i32 {
|
||||
return self.buffer.capacity() as i32 - self.writeOffset;
|
||||
}
|
||||
|
||||
fn ensureCapacity(&mut self, capacity: i32) {
|
||||
while capacity > self.getCapacity() {
|
||||
self.buffer.resize(self.buffer.capacity() * 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
fn isReadable(&self) -> bool {
|
||||
return self.writeOffset > self.readOffset;
|
||||
}
|
||||
|
||||
fn writeBytes(&mut self, bytes: &[i8]) {
|
||||
let length = bytes.len() as i32;
|
||||
self.ensureCapacity(length);
|
||||
for byte in bytes {
|
||||
self.writeByte(*byte);
|
||||
}
|
||||
}
|
||||
|
||||
fn readBytes(&mut self, count: i32) -> &[i8] {
|
||||
let value = &self.buffer[self.readOffset as usize..(self.readOffset + count) as usize];
|
||||
self.readOffset += count;
|
||||
return value;
|
||||
}
|
||||
|
||||
fn writeUBytes(&mut self, bytes: &[u8]) {
|
||||
let length = bytes.len() as i32;
|
||||
self.ensureCapacity(length);
|
||||
for byte in bytes {
|
||||
self.writeUByte(*byte);
|
||||
}
|
||||
}
|
||||
|
||||
fn readUBytes(&mut self, count: i32) -> Vec<u8> {
|
||||
let mut bytes: Vec<u8> = Vec::new();
|
||||
bytes.resize(count as usize, 0);
|
||||
for i in 0..count {
|
||||
bytes[i as usize] = self.readUByte();
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
fn toBytes(&self) -> &[i8] {
|
||||
return &self.buffer[0..self.writeOffset as usize];
|
||||
}
|
||||
|
||||
fn writeBool(&mut self, value: bool) {
|
||||
self.ensureCapacity(1);
|
||||
self.buffer[self.writeOffset as usize] = if value { 1 } else { 0 };
|
||||
self.writeOffset += 1;
|
||||
}
|
||||
|
||||
fn readBool(&mut self) -> bool {
|
||||
let value = self.buffer[self.readOffset as usize];
|
||||
self.readOffset += 1;
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
fn writeByte(&mut self, value: i8) {
|
||||
self.ensureCapacity(1);
|
||||
self.buffer[self.writeOffset as usize] = value;
|
||||
self.writeOffset += 1;
|
||||
}
|
||||
|
||||
fn readByte(&mut self) -> i8 {
|
||||
let value = self.buffer[self.readOffset as usize];
|
||||
self.readOffset += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
fn writeUByte(&mut self, value: u8) {
|
||||
self.ensureCapacity(1);
|
||||
self.buffer[self.writeOffset as usize] = value as i8;
|
||||
self.writeOffset += 1;
|
||||
}
|
||||
|
||||
fn readUByte(&mut self) -> u8 {
|
||||
let value = self.buffer[self.readOffset as usize];
|
||||
self.readOffset += 1;
|
||||
return value as u8;
|
||||
}
|
||||
|
||||
fn writeShort(&mut self, value: i16) {
|
||||
self.ensureCapacity(2);
|
||||
self.buffer[self.writeOffset as usize] = (value >> 8) as i8;
|
||||
self.buffer[self.writeOffset as usize + 1] = value as i8;
|
||||
self.writeOffset += 2;
|
||||
}
|
||||
|
||||
fn readShort(&mut self) -> i16 {
|
||||
let value = (self.buffer[self.readOffset as usize] as i16) << 8
|
||||
| (self.buffer[self.readOffset as usize + 1] as u8) as i16;
|
||||
self.readOffset += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
fn writeRawInt(&mut self, value: i32) {
|
||||
self.writeByte((value >> 24) as i8);
|
||||
self.writeByte((value >> 16) as i8);
|
||||
self.writeByte((value >> 8) as i8);
|
||||
self.writeByte(value as i8);
|
||||
}
|
||||
|
||||
fn readRawInt(&mut self) -> i32 {
|
||||
let value = (self.readUByte() as i32) << 24
|
||||
| (self.readUByte() as i32) << 16
|
||||
| (self.readUByte() as i32) << 8
|
||||
| (self.readUByte() as i32);
|
||||
return value;
|
||||
}
|
||||
|
||||
fn writeInt(&mut self, intValue: i32) {
|
||||
let value = ((intValue << 1) ^ (intValue >> 31)) as u32;
|
||||
|
||||
if (value >> 7 == 0) {
|
||||
self.writeByte(value as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >> 14 == 0) {
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte((value >> 7) as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >> 21 == 0) {
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte(((value >> 7) | 0x80) as i8);
|
||||
self.writeByte((value >> 14) as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >> 28 == 0) {
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte(((value >> 7) | 0x80) as i8);
|
||||
self.writeByte(((value >> 14) | 0x80) as i8);
|
||||
self.writeByte((value >> 21) as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte(((value >> 7) | 0x80) as i8);
|
||||
self.writeByte(((value >> 14) | 0x80) as i8);
|
||||
self.writeByte(((value >> 21) | 0x80) as i8);
|
||||
self.writeByte((value >> 28) as i8);
|
||||
}
|
||||
|
||||
fn writeIntCount(&mut self, intValue: i32) -> i32 {
|
||||
let value = ((intValue << 1) ^ (intValue >> 31)) as u32;
|
||||
if (value >> 7 == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (value >> 14 == 0) {
|
||||
return 2;
|
||||
}
|
||||
if (value >> 21 == 0) {
|
||||
return 3;
|
||||
}
|
||||
if (value >> 28 == 0) {
|
||||
return 4;
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
|
||||
fn readInt(&mut self) -> i32 {
|
||||
let mut b = self.readUByte() as u32;
|
||||
let mut value = b & 0x7F;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u32;
|
||||
value |= (b & 0x7F) << 7;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u32;
|
||||
value |= (b & 0x7F) << 14;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u32;
|
||||
value |= (b & 0x7F) << 21;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u32;
|
||||
value |= (b & 0x7F) << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (value >> 1) as i32 ^ -((value as i32) & 1);
|
||||
}
|
||||
|
||||
fn writeRawLong(&mut self, value: i64) {
|
||||
self.writeByte((value >> 56) as i8);
|
||||
self.writeByte((value >> 48) as i8);
|
||||
self.writeByte((value >> 40) as i8);
|
||||
self.writeByte((value >> 32) as i8);
|
||||
self.writeByte((value >> 24) as i8);
|
||||
self.writeByte((value >> 16) as i8);
|
||||
self.writeByte((value >> 8) as i8);
|
||||
self.writeByte(value as i8);
|
||||
}
|
||||
|
||||
fn readRawLong(&mut self) -> i64 {
|
||||
let value = (self.readUByte() as i64) << 56
|
||||
| (self.readUByte() as i64) << 48
|
||||
| (self.readUByte() as i64) << 40
|
||||
| (self.readUByte() as i64) << 32
|
||||
| (self.readUByte() as i64) << 24
|
||||
| (self.readUByte() as i64) << 16
|
||||
| (self.readUByte() as i64) << 8
|
||||
| (self.readUByte() as i64);
|
||||
return value;
|
||||
}
|
||||
|
||||
fn writeLong(&mut self, longValue: i64) {
|
||||
let value = ((longValue << 1) ^ (longValue >> 63)) as u64;
|
||||
|
||||
if (value >> 7 == 0) {
|
||||
self.writeByte(value as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >> 14 == 0) {
|
||||
self.writeByte(((value & 0x7F) | 0x80) as i8);
|
||||
self.writeByte((value >> 7) as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >> 21 == 0) {
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte(((value >> 7) | 0x80) as i8);
|
||||
self.writeByte((value >> 14) as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((value >> 28) == 0) {
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte(((value >> 7) | 0x80) as i8);
|
||||
self.writeByte(((value >> 14) | 0x80) as i8);
|
||||
self.writeByte((value >> 21) as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >> 35 == 0) {
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte(((value >> 7) | 0x80) as i8);
|
||||
self.writeByte(((value >> 14) | 0x80) as i8);
|
||||
self.writeByte(((value >> 21) | 0x80) as i8);
|
||||
self.writeByte((value >> 28) as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >> 42 == 0) {
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte(((value >> 7) | 0x80) as i8);
|
||||
self.writeByte(((value >> 14) | 0x80) as i8);
|
||||
self.writeByte(((value >> 21) | 0x80) as i8);
|
||||
self.writeByte(((value >> 28) | 0x80) as i8);
|
||||
self.writeByte((value >> 35) as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >> 49 == 0) {
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte(((value >> 7) | 0x80) as i8);
|
||||
self.writeByte(((value >> 14) | 0x80) as i8);
|
||||
self.writeByte(((value >> 21) | 0x80) as i8);
|
||||
self.writeByte(((value >> 28) | 0x80) as i8);
|
||||
self.writeByte(((value >> 35) | 0x80) as i8);
|
||||
self.writeByte((value >> 42) as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((value >> 56) == 0) {
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte(((value >> 7) | 0x80) as i8);
|
||||
self.writeByte(((value >> 14) | 0x80) as i8);
|
||||
self.writeByte(((value >> 21) | 0x80) as i8);
|
||||
self.writeByte(((value >> 28) | 0x80) as i8);
|
||||
self.writeByte(((value >> 35) | 0x80) as i8);
|
||||
self.writeByte(((value >> 42) | 0x80) as i8);
|
||||
self.writeByte((value >> 49) as i8);
|
||||
return;
|
||||
}
|
||||
|
||||
self.writeByte((value | 0x80) as i8);
|
||||
self.writeByte(((value >> 7) | 0x80) as i8);
|
||||
self.writeByte(((value >> 14) | 0x80) as i8);
|
||||
self.writeByte(((value >> 21) | 0x80) as i8);
|
||||
self.writeByte(((value >> 28) | 0x80) as i8);
|
||||
self.writeByte(((value >> 35) | 0x80) as i8);
|
||||
self.writeByte(((value >> 42) | 0x80) as i8);
|
||||
self.writeByte(((value >> 49) | 0x80) as i8);
|
||||
self.writeByte((value >> 56) as i8);
|
||||
}
|
||||
|
||||
fn readLong(&mut self) -> i64 {
|
||||
let mut b = self.readUByte() as u64;
|
||||
let mut value = b & 0x7F;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u64;
|
||||
value |= (b & 0x7F) << 7;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u64;
|
||||
value |= (b & 0x7F) << 14;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u64;
|
||||
value |= (b & 0x7F) << 21;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u64;
|
||||
value |= (b & 0x7F) << 28;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u64;
|
||||
value |= (b & 0x7F) << 35;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u64;
|
||||
value |= (b & 0x7F) << 42;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u64;
|
||||
value |= (b & 0x7F) << 49;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = self.readUByte() as u64;
|
||||
value |= b << 56;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (value >> 1) as i64 ^ -(value as i64 & 1);
|
||||
}
|
||||
|
||||
fn writeFloat(&mut self, value: f32) {
|
||||
self.writeRawInt(value.to_bits() as i32);
|
||||
}
|
||||
|
||||
fn readFloat(&mut self) -> f32 {
|
||||
return f32::from_bits(self.readRawInt() as u32);
|
||||
}
|
||||
|
||||
fn writeDouble(&mut self, value: f64) {
|
||||
self.writeRawLong(value.to_bits() as i64);
|
||||
}
|
||||
|
||||
fn readDouble(&mut self) -> f64 {
|
||||
return f64::from_bits(self.readRawLong() as u64);
|
||||
}
|
||||
|
||||
fn writeString(&mut self, value: &String) {
|
||||
if (value == "" || value.is_empty()) {
|
||||
self.writeInt(0);
|
||||
}
|
||||
let bytes = value.as_bytes();
|
||||
self.writeInt(bytes.len() as i32);
|
||||
self.writeUBytes(bytes);
|
||||
}
|
||||
|
||||
fn readString(&mut self) -> String {
|
||||
let length = self.readInt();
|
||||
if (length <= 0) {
|
||||
return String::from("");
|
||||
}
|
||||
let bytes = self.readUBytes(length);
|
||||
return String::from_utf8(bytes).unwrap();
|
||||
}
|
||||
|
||||
fn writePacket(&mut self, packet: &dyn Any, protocolId: i16) {
|
||||
write(self, packet, protocolId);
|
||||
}
|
||||
|
||||
fn readPacket(&mut self, protocolId: i16) -> Box<dyn Any> {
|
||||
return readByProtocolId(self, protocolId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
use std::any::Any;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub trait IPacket {
|
||||
fn protocolId(&self) -> i16;
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(unused_parens)]
|
||||
pub trait IByteBuffer {
|
||||
fn getBuffer(&self) -> &Vec<i8>;
|
||||
fn getWriteOffset(&self) -> i32;
|
||||
fn setWriteOffset(&mut self, writeIndex: i32);
|
||||
fn getReadOffset(&self) -> i32;
|
||||
fn setReadOffset(&mut self, readIndex: i32);
|
||||
fn getCapacity(&self) -> i32;
|
||||
fn ensureCapacity(&mut self, capacity: i32);
|
||||
fn isReadable(&self) -> bool;
|
||||
fn writeBytes(&mut self, bytes: &[i8]);
|
||||
fn readBytes(&mut self, count: i32) -> &[i8];
|
||||
fn writeUBytes(&mut self, bytes: &[u8]);
|
||||
fn readUBytes(&mut self, count: i32) -> Vec<u8>;
|
||||
fn toBytes(&self) -> &[i8];
|
||||
fn writeBool(&mut self, value: bool);
|
||||
fn readBool(&mut self) -> bool;
|
||||
fn writeByte(&mut self, value: i8);
|
||||
fn readByte(&mut self) -> i8;
|
||||
fn writeUByte(&mut self, value: u8);
|
||||
fn readUByte(&mut self) -> u8;
|
||||
fn writeShort(&mut self, value: i16);
|
||||
fn readShort(&mut self) -> i16;
|
||||
fn writeRawInt(&mut self, value: i32);
|
||||
fn readRawInt(&mut self) -> i32;
|
||||
fn writeInt(&mut self, intValue: i32);
|
||||
fn writeIntCount(&mut self, intValue: i32) -> i32;
|
||||
fn readInt(&mut self) -> i32;
|
||||
fn writeRawLong(&mut self, value: i64);
|
||||
fn readRawLong(&mut self) -> i64;
|
||||
fn writeLong(&mut self, longValue: i64);
|
||||
fn readLong(&mut self) -> i64;
|
||||
fn writeFloat(&mut self, value: f32);
|
||||
fn readFloat(&mut self) -> f32;
|
||||
fn writeDouble(&mut self, value: f64);
|
||||
fn readDouble(&mut self) -> f64;
|
||||
fn writeString(&mut self, value: &String);
|
||||
fn readString(&mut self) -> String;
|
||||
fn writePacket(&mut self, packet: &dyn Any, protocolId: i16);
|
||||
fn readPacket(&mut self, protocolId: i16) -> Box<dyn Any>;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
${protocol_note}
|
||||
pub struct ${protocol_name} {
|
||||
${protocol_field_definition}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use crate::${protocol_root_path}::i_byte_buffer::{IByteBuffer, IPacket};
|
||||
${protocol_imports}
|
||||
|
||||
pub fn write(buffer: &mut dyn IByteBuffer, packet: &dyn Any, protocolId: i16) {
|
||||
match protocolId {
|
||||
${protocol_write_serialization}
|
||||
_ => println!("protocolId:[{}] not found", protocolId)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(buffer: &mut dyn IByteBuffer) -> Box<dyn Any> {
|
||||
let protocolId = buffer.readShort();
|
||||
return readByProtocolId(buffer, protocolId);
|
||||
}
|
||||
|
||||
pub fn readByProtocolId(buffer: &mut dyn IByteBuffer, protocolId: i16) -> Box<dyn Any> {
|
||||
let packet = match protocolId {
|
||||
${protocol_read_deserialization}
|
||||
_ => Box::new(String::from("protocolId not found"))
|
||||
};
|
||||
return packet;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
impl IPacket for ${protocol_name} {
|
||||
fn protocolId(&self) -> i16 {
|
||||
return ${protocol_id};
|
||||
}
|
||||
}
|
||||
|
||||
impl ${protocol_name} {
|
||||
pub fn new() -> ${protocol_name} {
|
||||
let mut packet = ${protocol_name} {
|
||||
${protocol_field_definition}
|
||||
};
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write${protocol_name}(buffer: &mut dyn IByteBuffer, packet: &dyn Any) {
|
||||
let message = packet.downcast_ref::<${protocol_name}>().unwrap();
|
||||
${protocol_write_serialization}
|
||||
}
|
||||
|
||||
pub fn read${protocol_name}(buffer: &mut dyn IByteBuffer) -> Box<dyn Any> {
|
||||
let length = buffer.readInt();
|
||||
let mut packet = ${protocol_name}::new();
|
||||
if (length == 0) {
|
||||
return Box::new(packet);
|
||||
}
|
||||
let beforeReadIndex = buffer.getReadOffset();
|
||||
${protocol_read_deserialization}
|
||||
if (length > 0) {
|
||||
buffer.setReadOffset(beforeReadIndex + length);
|
||||
}
|
||||
return Box::new(packet);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use crate::${protocol_root_path}::i_byte_buffer::{IByteBuffer, IPacket};
|
||||
${protocol_imports}
|
||||
${protocol_class}
|
||||
|
||||
${protocol_registration}
|
||||
Reference in New Issue
Block a user