PhoenixGenerator  3.4.0
Generate code from template files and projects in C++, Rust, Python and wrapped C++ to Python
Loading...
Searching...
No Matches
generator_class_rust.cpp
Go to the documentation of this file.
1/***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : LGPL-3.0-only
5****************************************/
6
7#include "openFileStream.h"
8#include "header_generator.h"
9#include "rust_type_utils.h"
11
13
16bool rust_checkDefaultValueExist(const std::vector<PClassAttribute> & vecAttr){
17 bool hasDefaultValue = false;
18 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end() && !hasDefaultValue; ++it){
19 hasDefaultValue |= it->getDefaultValue() != "";
20 }
21 return hasDefaultValue;
22}
23
25
29bool generator_rust_enum_file(std::ofstream & fs, const PClassConfig & classConfig){
30 PString name(classConfig.getName());
31 const std::vector<PClassAttribute> & vecAttr(classConfig.getListAttribute());
32 if(vecAttr.size() == 0LU){
33 fs << "//Error : missing enum values as attribute for '" << name << "'" << std::endl;
34 return false;
35 }
36 if(classConfig.getClassDocumentation() != ""){fs << classConfig.getClassDocumentation() << std::endl;}
37 fs << "#[derive(Debug, Clone, Copy, PartialEq, Eq)]" << std::endl;
38 fs << "pub enum " << name << " {" << std::endl;
39 bool isDefaultCounterActivated = !rust_checkDefaultValueExist(vecAttr);
40 size_t i(0LU);
41 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
42 if(it->getDocumentation() != ""){fs << "\t" << it->getDocumentation() << std::endl;}
43 fs << "\t" << it->getName().toLower().firstToUpper();
44 if(isDefaultCounterActivated){
45 fs << " = " << i;
46 }else if(it->getDefaultValue() != ""){
47 fs << " = " << it->getDefaultValue();
48 }
49 fs << "," << std::endl;
50 ++i;
51 }
52 fs << "}" << std::endl << std::endl;
53
54 fs << "impl Default for " << name << " {" << std::endl;
55 fs << "\tfn default() -> Self {" << std::endl;
56 fs << "\t\t" << name << "::" << vecAttr.front().getName().toLower().firstToUpper() << std::endl;
57 fs << "\t}" << std::endl;
58 fs << "}" << std::endl << std::endl;
59 return true;
60}
61
63
69bool generator_rust_class_file(const PRustTraitBackendManager & manager, std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
70 PString name(classConfig.getName());
71 const std::vector<PClassAttribute> & vecAttr(classConfig.getListAttribute());
72
73 if(classConfig.getClassDocumentation() != ""){fs << classConfig.getClassDocumentation() << std::endl;}
74 fs << "#[derive(Debug, Clone, PartialEq)]" << std::endl;
75 fs << "pub struct " << name << " {" << std::endl;
76 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
77 if(it->getDocumentation() != ""){fs << "\t" << it->getDocumentation() << std::endl;}
78 fs << "\t" << it->getName().toSnakeCase() << ": " << getRustType(it->getType()) << "," << std::endl;
79 }
80 fs << "}" << std::endl << std::endl;
81
82 fs << "impl Default for " << name << " {" << std::endl;
83 fs << "\tfn default() -> Self {" << std::endl;
84 fs << "\t\t" << name << " {" << std::endl;
85 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
86 fs << "\t\t\t" << it->getName().toSnakeCase() << ": " << getRustAttributeDefaultValue(*it) << "," << std::endl;
87 }
88 fs << "\t\t}" << std::endl;
89 fs << "\t}" << std::endl;
90 fs << "}" << std::endl << std::endl;
91
92 fs << "impl " << name << " {" << std::endl;
93 fs << "\t///Creates a new " << name << " with default values" << std::endl;
94 fs << "\tpub fn new() -> Self { Self::default() }" << std::endl << std::endl;
95 manager.implMethodDeclaration(fs, classConfig, mode);
96 fs << "}" << std::endl << std::endl;
97 manager.classExtraDeclaration(fs, classConfig, mode);
98 return true;
99}
100
102
108bool generator_rust_class(const PRustTraitBackendManager & manager, const std::vector<PClassConfig> & vecClassConfig, const PPath & outputSourceDir, const PPath & baseFileName, const GeneratorMode & mode){
109 if(baseFileName == ""){return false;}
110 PPath rsFile = outputSourceDir / PPath(baseFileName.toSnakeCase() + PString(".rs"));
111 std::ofstream fs;
112 if(!openFileStream(fs, rsFile)){return false;}
113 licenceSave(fs);
114 manager.headerExtraInclude(fs, mode);
115 fs << std::endl;
116 bool b(true);
117 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
118 if(it->getIsEnum()){
119 b &= generator_rust_enum_file(fs, *it);
120 }else{
121 b &= generator_rust_class_file(manager, fs, *it, mode);
122 }
123 }
124 fs.close();
125 return b;
126}
127
129
137bool generator_rust_class_test(const PRustTraitBackendManager & manager, const PPath & outputTestDir, const PString & crateName, const PPath & baseFileName, const std::vector<PClassConfig> & vecClassConfig, const GeneratorMode & mode){
138 PString moduleName(baseFileName.toSnakeCase());
139 PPath testFile = outputTestDir / PPath(moduleName + PString("_test.rs"));
140 std::ofstream fs;
141 if(!openFileStream(fs, testFile)){return false;}
142 licenceSave(fs);
143 PString comma("");
144 fs << "use " << crateName << "::" << moduleName << "::{";
145 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
146 if(it->getIsEnum()){continue;}
147 fs << comma << it->getName();
148 comma = ", ";
149 }
150 fs << "};" << std::endl << std::endl;
151 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
152 manager.testFunction(fs, *it, mode);
153 }
154 fs.close();
155 return true;
156}
157
159
163bool generator_rust_class_full(const PRustTraitBackendManager & manager, const ProjectParam & projectParam){
164 bool b(true);
165 b &= projectParam.outputSourceDir.createDirectory();
166 if(projectParam.mode.enableUnitTest){
167 b &= projectParam.outputTestDir.createDirectory();
168 }
169 for(const PDataConfig & config : projectParam.vecDataConfig){
170 PPath baseFileName = config.getFileName().getFileName().eraseExtension();
171 b &= generator_rust_class(manager, config.getVecClassConfig(), projectParam.outputSourceDir, baseFileName, projectParam.mode);
172 if(projectParam.mode.enableUnitTest){
173 b &= generator_rust_class_test(manager, projectParam.outputTestDir, projectParam.mode.moduleName, baseFileName, config.getVecClassConfig(), projectParam.mode);
174 }
175 }
176 return b;
177}
Class to describe a basic class.
const PString & getClassDocumentation() const
Returns the class documentation.
const std::vector< PClassAttribute > & getListAttribute() const
Returns the list of attributes of the class.
const PString & getName() const
Returns the class name.
Class to describe a basic class.
Definition PDataConfig.h:17
const PVecClassConfig & getVecClassConfig() const
Get the vector of all config class of the current pdata file.
const PPath & getFileName() const
Get the file name of the current PDataConfig.
Manager of the Rust trait backends.
void classExtraDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of extra declarations.
void headerExtraInclude(std::ofstream &fs, const GeneratorMode &mode) const
Add extra include on the header.
void testFunction(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of test function.
void implMethodDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of the impl block methods.
bool generator_rust_enum_file(std::ofstream &fs, const PClassConfig &classConfig)
Write the Rust enum matching the given PClassConfig.
bool generator_rust_class_full(const PRustTraitBackendManager &manager, const ProjectParam &projectParam)
Generate the full Rust sources (and related integration tests) from configuration.
bool generator_rust_class(const PRustTraitBackendManager &manager, const std::vector< PClassConfig > &vecClassConfig, const PPath &outputSourceDir, const PPath &baseFileName, const GeneratorMode &mode)
Write the Rust module (one file per pdata file) containing every struct/enum it defines.
bool rust_checkDefaultValueExist(const std::vector< PClassAttribute > &vecAttr)
Check if the vector of PClassAttribute has default value.
bool generator_rust_class_test(const PRustTraitBackendManager &manager, const PPath &outputTestDir, const PString &crateName, const PPath &baseFileName, const std::vector< PClassConfig > &vecClassConfig, const GeneratorMode &mode)
Write the Rust integration test file (one file per pdata file) exercising every non-enum class it def...
bool generator_rust_class_file(const PRustTraitBackendManager &manager, std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
Write the Rust struct, Default implementation and getter/setter methods matching the given PClassConf...
void licenceSave(std::ofstream &fs)
Saves the policy.
PString getRustType(const PString &varType)
Get the Rust type matching a pdata type.
PString getRustAttributeDefaultValue(const PClassAttribute &attr)
Get the Rust literal default value of an attribute, as written into its Default impl.
All the genertor modes.
PString moduleName
Name of the wrapper python module.
bool enableUnitTest
True to enable the unit tests.
Set of parameters to generate a project.
GeneratorMode mode
Mode to be used to generate the project.
PPath outputTestDir
Output path of the unit tests.
PVecDataConfig vecDataConfig
Configuration of classes to be generated.
PPath outputSourceDir
Output path of the sources.