GCC Code Coverage Report


Directory: ./
File: src/BackEnd/generator_class_rust.cpp
Date: 2026-10-16 17:52:29
Exec Total Coverage
Lines: 101 105 96.2%
Functions: 6 6 100.0%
Branches: 208 235 88.5%

Line Branch Exec Source
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"
10 #include "generator_class_rust.h"
11
12 ///Check if the vector of PClassAttribute has default value
13 /** @param vecAttr : vector of attribute to be checked
14 * @return true if there is at least one default value, false if there is none
15 */
16 1 bool rust_checkDefaultValueExist(const std::vector<PClassAttribute> & vecAttr){
17 1 bool hasDefaultValue = false;
18
5/6
✓ Branch 0 (17→18) taken 2 times.
✓ Branch 1 (17→20) taken 1 times.
✓ Branch 2 (18→19) taken 2 times.
✗ Branch 3 (18→20) not taken.
✓ Branch 4 (21→3) taken 2 times.
✓ Branch 5 (21→22) taken 1 times.
6 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end() && !hasDefaultValue; ++it){
19
2/2
✓ Branch 0 (5→6) taken 2 times.
✓ Branch 2 (6→7) taken 2 times.
2 hasDefaultValue |= it->getDefaultValue() != "";
20 }
21 1 return hasDefaultValue;
22 }
23
24 ///Write the Rust enum matching the given PClassConfig
25 /** @param[out] fs : file to be completed
26 * @param classConfig : PClassConfig to be used
27 * @return true on success, false otherwise
28 */
29 1 bool generator_rust_enum_file(std::ofstream & fs, const PClassConfig & classConfig){
30
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 2 (3→4) taken 1 times.
1 PString name(classConfig.getName());
31
1/1
✓ Branch 0 (4→5) taken 1 times.
1 const std::vector<PClassAttribute> & vecAttr(classConfig.getListAttribute());
32
1/2
✗ Branch 0 (6→7) not taken.
✓ Branch 1 (6→12) taken 1 times.
1 if(vecAttr.size() == 0LU){
33 ✗ fs << "//Error : missing enum values as attribute for '" << name << "'" << std::endl;
34 ✗ return false;
35 }
36
6/7
✓ Branch 0 (12→13) taken 1 times.
✓ Branch 2 (13→14) taken 1 times.
✓ Branch 4 (14→15) taken 1 times.
✗ Branch 5 (14→18) not taken.
✓ Branch 6 (15→16) taken 1 times.
✓ Branch 8 (16→17) taken 1 times.
✓ Branch 10 (17→18) taken 1 times.
1 if(classConfig.getClassDocumentation() != ""){fs << classConfig.getClassDocumentation() << std::endl;}
37
2/2
✓ Branch 0 (18→19) taken 1 times.
✓ Branch 2 (19→20) taken 1 times.
1 fs << "#[derive(Debug, Clone, Copy, PartialEq, Eq)]" << std::endl;
38
4/4
✓ Branch 0 (20→21) taken 1 times.
✓ Branch 2 (21→22) taken 1 times.
✓ Branch 4 (22→23) taken 1 times.
✓ Branch 6 (23→24) taken 1 times.
1 fs << "pub enum " << name << " {" << std::endl;
39
1/1
✓ Branch 0 (24→25) taken 1 times.
1 bool isDefaultCounterActivated = !rust_checkDefaultValueExist(vecAttr);
40 1 size_t i(0LU);
41
2/2
✓ Branch 0 (71→26) taken 2 times.
✓ Branch 1 (71→72) taken 1 times.
6 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
42
3/8
✓ Branch 0 (28→29) taken 2 times.
✓ Branch 2 (29→30) taken 2 times.
✗ Branch 4 (30→31) not taken.
✓ Branch 5 (30→37) taken 2 times.
✗ Branch 6 (31→32) not taken.
✗ Branch 8 (34→35) not taken.
✗ Branch 10 (35→36) not taken.
✗ Branch 12 (36→37) not taken.
2 if(it->getDocumentation() != ""){fs << "\t" << it->getDocumentation() << std::endl;}
43
5/5
✓ Branch 0 (37→38) taken 2 times.
✓ Branch 2 (40→41) taken 2 times.
✓ Branch 4 (41→42) taken 2 times.
✓ Branch 6 (42→43) taken 2 times.
✓ Branch 8 (43→44) taken 2 times.
4 fs << "\t" << it->getName().toLower().firstToUpper();
44
1/2
✓ Branch 0 (46→47) taken 2 times.
✗ Branch 1 (46→49) not taken.
2 if(isDefaultCounterActivated){
45
2/2
✓ Branch 0 (47→48) taken 2 times.
✓ Branch 2 (48→59) taken 2 times.
2 fs << " = " << i;
46 ✗ }else if(it->getDefaultValue() != ""){
47 ✗ fs << " = " << it->getDefaultValue();
48 }
49
2/2
✓ Branch 0 (59→60) taken 2 times.
✓ Branch 2 (60→61) taken 2 times.
2 fs << "," << std::endl;
50 2 ++i;
51 }
52
3/3
✓ Branch 0 (72→73) taken 1 times.
✓ Branch 2 (73→74) taken 1 times.
✓ Branch 4 (74→75) taken 1 times.
1 fs << "}" << std::endl << std::endl;
53
54
4/4
✓ Branch 0 (75→76) taken 1 times.
✓ Branch 2 (76→77) taken 1 times.
✓ Branch 4 (77→78) taken 1 times.
✓ Branch 6 (78→79) taken 1 times.
1 fs << "impl Default for " << name << " {" << std::endl;
55
2/2
✓ Branch 0 (79→80) taken 1 times.
✓ Branch 2 (80→81) taken 1 times.
1 fs << "\tfn default() -> Self {" << std::endl;
56
8/8
✓ Branch 0 (81→82) taken 1 times.
✓ Branch 2 (82→83) taken 1 times.
✓ Branch 4 (83→84) taken 1 times.
✓ Branch 6 (85→86) taken 1 times.
✓ Branch 8 (86→87) taken 1 times.
✓ Branch 10 (87→88) taken 1 times.
✓ Branch 12 (88→89) taken 1 times.
✓ Branch 14 (89→90) taken 1 times.
1 fs << "\t\t" << name << "::" << vecAttr.front().getName().toLower().firstToUpper() << std::endl;
57
2/2
✓ Branch 0 (92→93) taken 1 times.
✓ Branch 2 (93→94) taken 1 times.
1 fs << "\t}" << std::endl;
58
3/3
✓ Branch 0 (94→95) taken 1 times.
✓ Branch 2 (95→96) taken 1 times.
✓ Branch 4 (96→97) taken 1 times.
1 fs << "}" << std::endl << std::endl;
59 1 return true;
60 1 }
61
62 ///Write the Rust struct, Default implementation and getter/setter methods matching the given PClassConfig
63 /** @param manager : PRustTraitBackendManager which handles all trait backend
64 * @param[out] fs : file to be completed
65 * @param classConfig : PClassConfig to be used
66 * @param mode : mode of the generator
67 * @return true on success, false otherwise
68 */
69 2 bool generator_rust_class_file(const PRustTraitBackendManager & manager, std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
70
2/2
✓ Branch 0 (2→3) taken 2 times.
✓ Branch 2 (3→4) taken 2 times.
2 PString name(classConfig.getName());
71
1/1
✓ Branch 0 (4→5) taken 2 times.
2 const std::vector<PClassAttribute> & vecAttr(classConfig.getListAttribute());
72
73
6/7
✓ Branch 0 (5→6) taken 2 times.
✓ Branch 2 (6→7) taken 2 times.
✓ Branch 4 (7→8) taken 2 times.
✗ Branch 5 (7→11) not taken.
✓ Branch 6 (8→9) taken 2 times.
✓ Branch 8 (9→10) taken 2 times.
✓ Branch 10 (10→11) taken 2 times.
2 if(classConfig.getClassDocumentation() != ""){fs << classConfig.getClassDocumentation() << std::endl;}
74
2/2
✓ Branch 0 (11→12) taken 2 times.
✓ Branch 2 (12→13) taken 2 times.
2 fs << "#[derive(Debug, Clone, PartialEq)]" << std::endl;
75
4/4
✓ Branch 0 (13→14) taken 2 times.
✓ Branch 2 (14→15) taken 2 times.
✓ Branch 4 (15→16) taken 2 times.
✓ Branch 6 (16→17) taken 2 times.
2 fs << "pub struct " << name << " {" << std::endl;
76
2/2
✓ Branch 0 (55→18) taken 5 times.
✓ Branch 1 (55→56) taken 2 times.
14 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
77
7/8
✓ Branch 0 (20→21) taken 5 times.
✓ Branch 2 (21→22) taken 5 times.
✓ Branch 4 (22→23) taken 5 times.
✗ Branch 5 (22→29) not taken.
✓ Branch 6 (23→24) taken 5 times.
✓ Branch 8 (26→27) taken 5 times.
✓ Branch 10 (27→28) taken 5 times.
✓ Branch 12 (28→29) taken 5 times.
10 if(it->getDocumentation() != ""){fs << "\t" << it->getDocumentation() << std::endl;}
78
10/10
✓ Branch 0 (29→30) taken 5 times.
✓ Branch 2 (32→33) taken 5 times.
✓ Branch 4 (33→34) taken 5 times.
✓ Branch 6 (34→35) taken 5 times.
✓ Branch 8 (35→36) taken 5 times.
✓ Branch 10 (38→39) taken 5 times.
✓ Branch 12 (39→40) taken 5 times.
✓ Branch 14 (40→41) taken 5 times.
✓ Branch 16 (41→42) taken 5 times.
✓ Branch 18 (42→43) taken 5 times.
15 fs << "\t" << it->getName().toSnakeCase() << ": " << getRustType(it->getType()) << "," << std::endl;
79 }
80
3/3
✓ Branch 0 (56→57) taken 2 times.
✓ Branch 2 (57→58) taken 2 times.
✓ Branch 4 (58→59) taken 2 times.
2 fs << "}" << std::endl << std::endl;
81
82
4/4
✓ Branch 0 (59→60) taken 2 times.
✓ Branch 2 (60→61) taken 2 times.
✓ Branch 4 (61→62) taken 2 times.
✓ Branch 6 (62→63) taken 2 times.
2 fs << "impl Default for " << name << " {" << std::endl;
83
2/2
✓ Branch 0 (63→64) taken 2 times.
✓ Branch 2 (64→65) taken 2 times.
2 fs << "\tfn default() -> Self {" << std::endl;
84
4/4
✓ Branch 0 (65→66) taken 2 times.
✓ Branch 2 (66→67) taken 2 times.
✓ Branch 4 (67→68) taken 2 times.
✓ Branch 6 (68→69) taken 2 times.
2 fs << "\t\t" << name << " {" << std::endl;
85
2/2
✓ Branch 0 (95→70) taken 5 times.
✓ Branch 1 (95→96) taken 2 times.
14 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
86
9/9
✓ Branch 0 (70→71) taken 5 times.
✓ Branch 2 (73→74) taken 5 times.
✓ Branch 4 (74→75) taken 5 times.
✓ Branch 6 (75→76) taken 5 times.
✓ Branch 8 (76→77) taken 5 times.
✓ Branch 10 (79→80) taken 5 times.
✓ Branch 12 (80→81) taken 5 times.
✓ Branch 14 (81→82) taken 5 times.
✓ Branch 16 (82→83) taken 5 times.
15 fs << "\t\t\t" << it->getName().toSnakeCase() << ": " << getRustAttributeDefaultValue(*it) << "," << std::endl;
87 }
88
2/2
✓ Branch 0 (96→97) taken 2 times.
✓ Branch 2 (97→98) taken 2 times.
2 fs << "\t\t}" << std::endl;
89
2/2
✓ Branch 0 (98→99) taken 2 times.
✓ Branch 2 (99→100) taken 2 times.
2 fs << "\t}" << std::endl;
90
3/3
✓ Branch 0 (100→101) taken 2 times.
✓ Branch 2 (101→102) taken 2 times.
✓ Branch 4 (102→103) taken 2 times.
2 fs << "}" << std::endl << std::endl;
91
92
4/4
✓ Branch 0 (103→104) taken 2 times.
✓ Branch 2 (104→105) taken 2 times.
✓ Branch 4 (105→106) taken 2 times.
✓ Branch 6 (106→107) taken 2 times.
2 fs << "impl " << name << " {" << std::endl;
93
4/4
✓ Branch 0 (107→108) taken 2 times.
✓ Branch 2 (108→109) taken 2 times.
✓ Branch 4 (109→110) taken 2 times.
✓ Branch 6 (110→111) taken 2 times.
2 fs << "\t///Creates a new " << name << " with default values" << std::endl;
94
3/3
✓ Branch 0 (111→112) taken 2 times.
✓ Branch 2 (112→113) taken 2 times.
✓ Branch 4 (113→114) taken 2 times.
2 fs << "\tpub fn new() -> Self { Self::default() }" << std::endl << std::endl;
95
1/1
✓ Branch 0 (114→115) taken 2 times.
2 manager.implMethodDeclaration(fs, classConfig, mode);
96
3/3
✓ Branch 0 (115→116) taken 2 times.
✓ Branch 2 (116→117) taken 2 times.
✓ Branch 4 (117→118) taken 2 times.
2 fs << "}" << std::endl << std::endl;
97
1/1
✓ Branch 0 (118→119) taken 2 times.
2 manager.classExtraDeclaration(fs, classConfig, mode);
98 2 return true;
99 2 }
100
101 ///Write the Rust module (one file per pdata file) containing every struct/enum it defines
102 /** @param manager : PRustTraitBackendManager which handles all trait backend
103 * @param rsFile : file to be saved
104 * @param vecClassConfig : configuration of the classes to be used
105 * @param mode : mode of the generator
106 * @return true on success, false otherwise
107 */
108 2 bool generator_rust_class(const PRustTraitBackendManager & manager, const std::vector<PClassConfig> & vecClassConfig, const PPath & outputSourceDir, const PPath & baseFileName, const GeneratorMode & mode){
109
2/3
✓ Branch 0 (2→3) taken 2 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 2 times.
2 if(baseFileName == ""){return false;}
110
6/6
✓ Branch 0 (5→6) taken 2 times.
✓ Branch 2 (6→7) taken 2 times.
✓ Branch 4 (7→8) taken 2 times.
✓ Branch 6 (8→9) taken 2 times.
✓ Branch 8 (9→10) taken 2 times.
✓ Branch 10 (10→11) taken 2 times.
2 PPath rsFile = outputSourceDir / PPath(baseFileName.toSnakeCase() + PString(".rs"));
111
1/1
✓ Branch 0 (16→17) taken 2 times.
2 std::ofstream fs;
112
2/3
✓ Branch 0 (17→18) taken 2 times.
✗ Branch 2 (18→19) not taken.
✓ Branch 3 (18→20) taken 2 times.
2 if(!openFileStream(fs, rsFile)){return false;}
113
1/1
✓ Branch 0 (20→21) taken 2 times.
2 licenceSave(fs);
114
1/1
✓ Branch 0 (21→22) taken 2 times.
2 manager.headerExtraInclude(fs, mode);
115
1/1
✓ Branch 0 (22→23) taken 2 times.
2 fs << std::endl;
116 2 bool b(true);
117
2/2
✓ Branch 0 (46→24) taken 3 times.
✓ Branch 1 (46→47) taken 2 times.
10 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
118
3/3
✓ Branch 0 (26→27) taken 3 times.
✓ Branch 2 (27→28) taken 1 times.
✓ Branch 3 (27→32) taken 2 times.
3 if(it->getIsEnum()){
119
1/1
✓ Branch 0 (30→31) taken 1 times.
1 b &= generator_rust_enum_file(fs, *it);
120 }else{
121
1/1
✓ Branch 0 (34→35) taken 2 times.
2 b &= generator_rust_class_file(manager, fs, *it, mode);
122 }
123 }
124
1/1
✓ Branch 0 (47→48) taken 2 times.
2 fs.close();
125 2 return b;
126 2 }
127
128 ///Write the Rust integration test file (one file per pdata file) exercising every non-enum class it defines
129 /** @param manager : PRustTraitBackendManager which handles all trait backend
130 * @param outputTestDir : directory where to save the test
131 * @param crateName : name of the Cargo crate the generated sources belong to
132 * @param moduleName : name of the Rust module (matches the generated source file base name)
133 * @param vecClassConfig : configuration of the classes to be used
134 * @param mode : mode of the generator
135 * @return true on success, false otherwise
136 */
137 2 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){
138
1/1
✓ Branch 0 (2→3) taken 2 times.
2 PString moduleName(baseFileName.toSnakeCase());
139
5/5
✓ Branch 0 (3→4) taken 2 times.
✓ Branch 2 (4→5) taken 2 times.
✓ Branch 4 (5→6) taken 2 times.
✓ Branch 6 (6→7) taken 2 times.
✓ Branch 8 (7→8) taken 2 times.
2 PPath testFile = outputTestDir / PPath(moduleName + PString("_test.rs"));
140
1/1
✓ Branch 0 (12→13) taken 2 times.
2 std::ofstream fs;
141
2/3
✓ Branch 0 (13→14) taken 2 times.
✗ Branch 2 (14→15) not taken.
✓ Branch 3 (14→16) taken 2 times.
2 if(!openFileStream(fs, testFile)){return false;}
142
1/1
✓ Branch 0 (16→17) taken 2 times.
2 licenceSave(fs);
143
1/1
✓ Branch 0 (17→18) taken 2 times.
2 PString comma("");
144
5/5
✓ Branch 0 (18→19) taken 2 times.
✓ Branch 2 (19→20) taken 2 times.
✓ Branch 4 (20→21) taken 2 times.
✓ Branch 6 (21→22) taken 2 times.
✓ Branch 8 (22→23) taken 2 times.
2 fs << "use " << crateName << "::" << moduleName << "::{";
145
2/2
✓ Branch 0 (45→24) taken 3 times.
✓ Branch 1 (45→46) taken 2 times.
10 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
146
3/3
✓ Branch 0 (26→27) taken 3 times.
✓ Branch 2 (27→28) taken 1 times.
✓ Branch 3 (27→29) taken 2 times.
3 if(it->getIsEnum()){continue;}
147
3/3
✓ Branch 0 (29→30) taken 2 times.
✓ Branch 2 (32→33) taken 2 times.
✓ Branch 4 (33→34) taken 2 times.
4 fs << comma << it->getName();
148
1/1
✓ Branch 0 (34→35) taken 2 times.
2 comma = ", ";
149 }
150
3/3
✓ Branch 0 (46→47) taken 2 times.
✓ Branch 2 (47→48) taken 2 times.
✓ Branch 4 (48→49) taken 2 times.
2 fs << "};" << std::endl << std::endl;
151
2/2
✓ Branch 0 (63→50) taken 3 times.
✓ Branch 1 (63→64) taken 2 times.
10 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
152
1/1
✓ Branch 0 (52→53) taken 3 times.
3 manager.testFunction(fs, *it, mode);
153 }
154
1/1
✓ Branch 0 (64→65) taken 2 times.
2 fs.close();
155 2 return true;
156 2 }
157
158 ///Generate the full Rust sources (and related integration tests) from configuration
159 /** @param manager : PRustTraitBackendManager which handles all trait backend
160 * @param projectParam : description of classes and how and where to generate sources and test
161 * @return true on success, false otherwise
162 */
163 1 bool generator_rust_class_full(const PRustTraitBackendManager & manager, const ProjectParam & projectParam){
164 1 bool b(true);
165 1 b &= projectParam.outputSourceDir.createDirectory();
166
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
1 if(projectParam.mode.enableUnitTest){
167 1 b &= projectParam.outputTestDir.createDirectory();
168 }
169
2/2
✓ Branch 0 (31→8) taken 2 times.
✓ Branch 1 (31→32) taken 1 times.
4 for(const PDataConfig & config : projectParam.vecDataConfig){
170
4/4
✓ Branch 0 (10→11) taken 2 times.
✓ Branch 2 (11→12) taken 2 times.
✓ Branch 4 (12→13) taken 2 times.
✓ Branch 6 (13→14) taken 2 times.
2 PPath baseFileName = config.getFileName().getFileName().eraseExtension();
171
2/2
✓ Branch 0 (15→16) taken 2 times.
✓ Branch 2 (16→17) taken 2 times.
2 b &= generator_rust_class(manager, config.getVecClassConfig(), projectParam.outputSourceDir, baseFileName, projectParam.mode);
172
1/2
✓ Branch 0 (17→18) taken 2 times.
✗ Branch 1 (17→21) not taken.
2 if(projectParam.mode.enableUnitTest){
173
2/2
✓ Branch 0 (18→19) taken 2 times.
✓ Branch 2 (19→20) taken 2 times.
2 b &= generator_rust_class_test(manager, projectParam.outputTestDir, projectParam.mode.moduleName, baseFileName, config.getVecClassConfig(), projectParam.mode);
174 }
175 2 }
176 1 return b;
177 }
178