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>

Reply via email to