This is an automated email from the ASF dual-hosted git repository.
jfeinauer pushed a commit to branch feature/plc4rs
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/plc4rs by this push:
new 69a4d35012 Further progress in ser / deser for "non-discriminated"
types
69a4d35012 is described below
commit 69a4d350122f14fc7b3ebadb52a51dc7f09c2d39
Author: julian <[email protected]>
AuthorDate: Mon Jun 6 11:27:47 2022 +0200
Further progress in ser / deser for "non-discriminated" types
---
.../language/rust/RustLanguageTemplateHelper.java | 94 ++++++++++++++++++++--
.../templates/rust/complex-type-template.rs.ftlh | 84 +++++++++++++++++--
2 files changed, 166 insertions(+), 12 deletions(-)
diff --git
a/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
b/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
index 76fb4a98c4..03426a41ed 100644
---
a/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
+++
b/code-generation/language-rust/src/main/java/org/apache/plc4x/language/rust/RustLanguageTemplateHelper.java
@@ -25,6 +25,7 @@ import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.D
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.DefaultEnumTypeDefinition;
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.fields.DefaultDiscriminatorField;
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.fields.DefaultSwitchField;
+import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.fields.DefaultTypedNamedField;
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultArrayTypeReference;
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultEnumTypeReference;
import
org.apache.plc4x.plugins.codegenerator.language.mspec.model.terms.DefaultBooleanLiteral;
@@ -47,6 +48,7 @@ import java.time.LocalTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
@SuppressWarnings({"unused", "WeakerAccess"})
public class RustLanguageTemplateHelper extends
BaseFreemarkerLanguageTemplateHelper {
@@ -206,12 +208,14 @@ public class RustLanguageTemplateHelper extends
BaseFreemarkerLanguageTemplateHe
if (type instanceof ComplexTypeReference) {
String typeName = ((ComplexTypeReference)
type).getName();
imports.add(new String[]{typeName, typeName});
+ imports.add(new String[]{typeName, typeName +
"Options"});
} else if (type instanceof DefaultArrayTypeReference) {
// TODO refactor to make this more elgant
TypeReference elementTypeReference =
((DefaultArrayTypeReference) type).getElementTypeReference();
if (elementTypeReference instanceof
ComplexTypeReference) {
String typeName = ((ComplexTypeReference)
elementTypeReference).getName();
imports.add(new String[]{typeName, typeName});
+ imports.add(new String[]{typeName, typeName +
"Options"});
}
} else if (type instanceof DefaultEnumTypeReference) {
String typeName = ((DefaultEnumTypeReference)
type).getName();
@@ -360,6 +364,63 @@ public class RustLanguageTemplateHelper extends
BaseFreemarkerLanguageTemplateHe
});
}
+ public String getWriteFunctionCall(DefaultTypedNamedField field) {
+ TypeReference typeReference = field.getType();
+ SimpleTypeReference simpleTypeReference;
+ if (typeReference instanceof SimpleTypeReference) {
+ simpleTypeReference = (SimpleTypeReference) typeReference;
+ } else if (typeReference instanceof DefaultEnumTypeReference) {
+ if (((DefaultEnumTypeReference)
typeReference).getBaseTypeReference().isPresent()) {
+ simpleTypeReference = ((DefaultEnumTypeReference)
typeReference).getBaseTypeReference().get();
+ } else {
+ throw new RuntimeException("No idea whats happening here?!");
+ }
+ } else if (typeReference instanceof DefaultArrayTypeReference) {
+ // Get length
+ TypeReference elementTypeReference = ((DefaultArrayTypeReference)
typeReference).getElementTypeReference();
+ if (elementTypeReference instanceof SimpleTypeReference) {
+ if (((SimpleTypeReference) elementTypeReference).getBaseType()
== SimpleTypeReference.SimpleBaseType.BYTE) {
+ return "writer.write_bytes(self." + field.getName() +
".as_slice())?";
+ }
+ } else if (elementTypeReference instanceof ComplexTypeReference) {
+ return "// not handled yet";
+ }
+ return "// not handled yet";
+// throw new RuntimeException("Not implemented yet: " +
typeReference);
+ } else if (typeReference instanceof ComplexTypeReference) {
+ // Just call the parse method on it
+ String typeName = ((ComplexTypeReference)
typeReference).getTypeDefinition().getName();
+ // Get Options
+ List<Argument> parserArguments = ((ComplexTypeReference)
typeReference).getTypeDefinition().getParserArguments().orElse(Collections.emptyList());
+ String options = parserArguments.stream().map(argument ->
argument.getName()).collect(Collectors.joining(","));
+ return "self." + field.getName() + ".serialize(writer)?";
+ } else {
+ return "// not handled yet";
+// throw new RuntimeException("Not implemented yet: " +
typeReference);
+ }
+ SimpleTypeReference.SimpleBaseType baseType;
+ baseType = simpleTypeReference.getBaseType();
+ switch (baseType) {
+ case BIT:
+ return "writer.write_bit(self." + field.getName() + ")?";
+ case UINT:
+ IntegerTypeReference unsignedIntegerTypeReference =
(IntegerTypeReference) simpleTypeReference;
+ if (unsignedIntegerTypeReference.getSizeInBits() < 8) {
+ return "writer.write_u_n(self." +
unsignedIntegerTypeReference.getSizeInBits() + ", self." + field.getName() + "
as u64)? as u8";
+ }
+ if (unsignedIntegerTypeReference.getSizeInBits() == 8) {
+ return "writer.write_u8(self." + field.getName() + ")?";
+ }
+ if (unsignedIntegerTypeReference.getSizeInBits() < 16) {
+ return "writer.write_u_n(self." +
unsignedIntegerTypeReference.getSizeInBits() + ", self." + field.getName() + "
as u64)? as u16";
+ }
+ if (unsignedIntegerTypeReference.getSizeInBits() == 16) {
+ return "writer.write_u16(self." + field.getName() + ")?";
+ }
+ }
+ throw new RuntimeException("Not implemented yet: " + typeReference);
+ }
+
public String getReadFunctionCall(TypeReference typeReference) {
SimpleTypeReference simpleTypeReference;
if (typeReference instanceof SimpleTypeReference) {
@@ -370,27 +431,46 @@ public class RustLanguageTemplateHelper extends
BaseFreemarkerLanguageTemplateHe
} else {
throw new RuntimeException("No idea whats happening here?!");
}
+ } else if (typeReference instanceof DefaultArrayTypeReference) {
+ // Get length
+ TypeReference elementTypeReference = ((DefaultArrayTypeReference)
typeReference).getElementTypeReference();
+ if (elementTypeReference instanceof SimpleTypeReference) {
+ if (((SimpleTypeReference) elementTypeReference).getBaseType()
== SimpleTypeReference.SimpleBaseType.BYTE) {
+ return "reader.read_bytes()?";
+ }
+ } else if (elementTypeReference instanceof ComplexTypeReference) {
+ return "// not handled yet";
+ }
+ throw new RuntimeException("Not implemented yet: " +
typeReference);
+ } else if (typeReference instanceof ComplexTypeReference) {
+ // Just call the parse method on it
+ String typeName = ((ComplexTypeReference)
typeReference).getTypeDefinition().getName();
+ // Get Options
+ List<Argument> parserArguments = ((ComplexTypeReference)
typeReference).getTypeDefinition().getParserArguments().orElse(Collections.emptyList());
+ String options = parserArguments.stream().map(argument ->
argument.getName()).collect(Collectors.joining(","));
+ return typeName + "::parse(reader, Some(" + typeName + "Options {
" + options + " }))?";
} else {
- throw new RuntimeException("Not implemented yet!");
+ return "// not handled yet";
+// throw new RuntimeException("Not implemented yet: " +
typeReference);
}
SimpleTypeReference.SimpleBaseType baseType;
baseType = simpleTypeReference.getBaseType();
switch (baseType) {
case BIT:
- return "read_bit()?";
+ return "reader.read_bit()?";
case UINT:
IntegerTypeReference unsignedIntegerTypeReference =
(IntegerTypeReference) simpleTypeReference;
if (unsignedIntegerTypeReference.getSizeInBits() < 8) {
- return "read_u_n(" +
unsignedIntegerTypeReference.getSizeInBits() + ")? as u8";
+ return "reader.read_u_n(" +
unsignedIntegerTypeReference.getSizeInBits() + ")? as u8";
}
if (unsignedIntegerTypeReference.getSizeInBits() == 8) {
- return "read_u8()?";
+ return "reader.read_u8()?";
}
if (unsignedIntegerTypeReference.getSizeInBits() < 16) {
- return "read_u_n(" +
unsignedIntegerTypeReference.getSizeInBits() + ")? as u16";
+ return "reader.read_u_n(" +
unsignedIntegerTypeReference.getSizeInBits() + ")? as u16";
}
if (unsignedIntegerTypeReference.getSizeInBits() == 16) {
- return "read_u16()?";
+ return "reader.read_u16()?";
}
}
throw new RuntimeException("Not implemented yet: " + typeReference);
@@ -418,7 +498,7 @@ public class RustLanguageTemplateHelper extends
BaseFreemarkerLanguageTemplateHe
case BIT:
return "bool";
case BYTE:
- return "i8";
+ return "u8";
case UINT:
IntegerTypeReference unsignedIntegerTypeReference =
(IntegerTypeReference) simpleTypeReference;
if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
diff --git
a/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
b/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
index 08bfbf5551..b5a480c427 100644
---
a/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
+++
b/code-generation/language-rust/src/main/resources/templates/rust/complex-type-template.rs.ftlh
@@ -139,9 +139,11 @@ impl Message for ${type.name} {
}
<#else>
<#if field.isSimpleField()>
- let ${field.name} = reader.${helper.getReadFunctionCall(field.type)};
+ let ${field.name} = ${helper.getReadFunctionCall(field.type)};
+ <#elseif field.isDiscriminatorField()>
+ let ${field.name} = ${helper.getReadFunctionCall(field.type)};
<#else>
- -> ${field}
+ // -> ${field}
</#if>
</#if>
<#-- ${helper.generateFieldParseCode(field)}-->
@@ -154,8 +156,22 @@ pub struct ${type.name} {
<#list type.fields as field>
<#if field.isSimpleField()>
pub ${field.name}:
${helper.getLanguageTypeNameForTypeReference(field.type)}<#sep>,</#sep>
+ <#elseif field.isArrayField()>
+ pub ${field.name}:
${helper.getLanguageTypeNameForTypeReference(field.type)}<#sep>,</#sep>
+ <#elseif field.isConstField()>
+ // Intentionally do nothing
<#else>
- -> ${field}
+ // -> ${field}
+ </#if>
+ </#list>
+}
+
+impl ${type.name} {
+ <#list type.fields as field>
+ <#if field.isImplicitField()>
+ pub fn ${field.name}(&mut self) ->
${helper.getLanguageTypeNameForTypeReference(field.type)} {
+ 0
+ }
</#if>
</#list>
}
@@ -169,11 +185,69 @@ impl Message for ${type.name} {
}
fn serialize<T: Write>(&self, writer: &mut WriteBuffer<T>) ->
Result<usize, Error> {
- todo!()
+ <#list type.fields as field>
+ ${helper.getWriteFunctionCall(field)};
+<#-- <#if field.isArrayField()>-->
+<#-- //
writer.write_${helper.getLanguageTypeNameForTypeReference(field.type)}(self.${field.name})?;-->
+<#-- <#elseif field.isImplicitField()>-->
+<#--
writer.write_${helper.getLanguageTypeNameForTypeReference(field.type)}(self.${field.name}())?;-->
+<#-- <#elseif field.isConstField()>-->
+<#-- <#else>-->
+<#--
writer.write_${helper.getLanguageTypeNameForTypeReference(field.type)}(self.${field.name})?;-->
+<#-- </#if>-->
+<#-- <#elseif field.isArrayField()>-->
+<#-- pub ${field.name}:
${helper.getLanguageTypeNameForTypeReference(field.type)}<#sep>,</#sep>-->
+<#-- <#else>-->
+<#-- // -> ${field}-->
+<#-- </#if>-->
+ </#list>
+ Ok(0)
}
fn parse<T: Read>(reader: &mut ReadBuffer<T>, parameter: Option<Self::P>)
-> Result<Self::M, Error> {
- todo!()
+ // (Re-)define the options
+ let parameter = parameter.unwrap();
+ <#if type.parserArguments?? && !type.parserArguments.isEmpty()>
+ <#if type.parserArguments.isPresent()>
+ <#list type.parserArguments.get() as arg>
+ let ${arg.name} = parameter.${arg.name};
+ </#list>
+ </#if>
+ </#if>
+ <#if !type.parentType.isEmpty()>
+ <#if type.parentType.get().parserArguments?? &&
!type.parentType.get().parserArguments.isEmpty()>
+ <#if type.parentType.get().parserArguments.isPresent()>
+ <#list type.parentType.get().parserArguments.get() as arg>
+ let ${arg.name} = parameter.${arg.name};
+ </#list>
+ </#if>
+ </#if>
+ </#if>
+ <#list type.fields as field>
+ <#if field.isArrayField()>
+ let ${field.name} = vec![];
+ let ${field.name}_read = 0 as usize;
+ <#if field.loopType == "LENGTH">
+ // while ${field.name}_read < ${field.loopExpression} {
+ // do something
+ // }
+ </#if>
+ <#if field.loopType == "COUNT">
+ // for _ in 0..(${field.loopExpression}) {
+ // do something
+ // }
+ </#if>
+ <#else>
+ let ${field.name} = ${helper.getReadFunctionCall(field.type)};
+ </#if>
+ </#list>
+ Ok(Self::M {
+ <#list type.fields as field>
+ <#if !field.isImplicitField() && !field.isConstField()>
+ ${field.name}<#sep>,</#sep>
+ </#if>
+ </#list>
+ })
}
}
</#if>