rccn-gen 1.0.3__py3-none-any.whl → 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rccn_gen/systems.py +57 -16
- rccn_gen/text_modules/cargo_toml/cargo.txt +4 -1
- rccn_gen/text_modules/command/command_module_enum.txt +2 -1
- rccn_gen/text_modules/main/main.txt +1 -0
- rccn_gen/text_modules/main/service_module_import_service.txt +1 -1
- rccn_gen/text_modules/service/service.txt +1 -1
- rccn_gen/utils.py +22 -12
- {rccn_gen-1.0.3.dist-info → rccn_gen-1.1.0.dist-info}/METADATA +38 -7
- {rccn_gen-1.0.3.dist-info → rccn_gen-1.1.0.dist-info}/RECORD +10 -10
- {rccn_gen-1.0.3.dist-info → rccn_gen-1.1.0.dist-info}/WHEEL +0 -0
rccn_gen/systems.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from yamcs.pymdb import System, Subsystem, Command, Container
|
1
|
+
from yamcs.pymdb import System, Subsystem, Command, Container, AndExpression, EqExpression
|
2
2
|
import shutil
|
3
3
|
import difflib
|
4
4
|
import datetime
|
@@ -189,7 +189,7 @@ class Service(Subsystem):
|
|
189
189
|
def __init__(
|
190
190
|
self,
|
191
191
|
name: str,
|
192
|
-
service_id: int
|
192
|
+
service_id: int,
|
193
193
|
*args,
|
194
194
|
**kwargs
|
195
195
|
):
|
@@ -256,7 +256,7 @@ class Service(Subsystem):
|
|
256
256
|
return paths
|
257
257
|
|
258
258
|
def rccn_commands(self):
|
259
|
-
return [command for command in self.commands if isinstance(command, RCCNCommand)]
|
259
|
+
return [command for command in self.commands if isinstance(command, RCCNCommand) and command.name != 'base']
|
260
260
|
|
261
261
|
def find_and_replace_keywords(self, text, text_modules_path):
|
262
262
|
# Find and replace service module keywords
|
@@ -272,16 +272,13 @@ class Service(Subsystem):
|
|
272
272
|
replacement_text = (self.find_and_replace_keywords(module_text, text_modules_path) + '\n')
|
273
273
|
text = insert_before_with_indentation(text, service_module_keyword, replacement_text)
|
274
274
|
|
275
|
-
# Call keyword replacement for all associated commands (Later, there needs to be checking to account for user changes to the generated files)
|
276
|
-
if len(self.rccn_commands()) == 0:
|
277
|
-
print('RCCN-Gen: Service '+self.name+' does not have any commands associated with it.')
|
278
275
|
for command in self.rccn_commands():
|
279
276
|
text = command.find_and_replace_keywords(text, text_modules_path)
|
280
277
|
|
281
278
|
# Find and replace service variable keywords
|
282
279
|
var_keywords = get_var_keywords(text)
|
283
280
|
service_var_translation = {
|
284
|
-
'<<VAR_SERVICE_NAME>>': lambda: self.name,
|
281
|
+
'<<VAR_SERVICE_NAME>>': lambda: snakecase(self.name),
|
285
282
|
'<<VAR_SERVICE_ID>>': lambda: str(self.service_id),
|
286
283
|
'<<VAR_SERVICE_NAME_UCASE>>': lambda: pascalcase(self.name),
|
287
284
|
'<<VAR_SERVICE_TELEMETRY>>': lambda: self.generate_rust_telemetry_definition(),
|
@@ -325,7 +322,7 @@ class Service(Subsystem):
|
|
325
322
|
self.generate_snapshot('command', 'command_user_snapshot')
|
326
323
|
# Generate command.rs file
|
327
324
|
if len(self.rccn_commands()) == 0:
|
328
|
-
print('RCCN-
|
325
|
+
print('RCCN-Information: Service \''+self.name+'\' has no commands other than base command. Generation of command.rs file will be skipped.')
|
329
326
|
return
|
330
327
|
command_file_path = self.file_paths()['command_template']
|
331
328
|
with open(command_file_path, 'r') as file:
|
@@ -395,22 +392,28 @@ class RCCNCommand(Command):
|
|
395
392
|
self.init_kwargs = kwargs
|
396
393
|
if 'system' in kwargs and isinstance(kwargs['system'], Service):
|
397
394
|
self.add_to_service(kwargs['system'])
|
395
|
+
elif 'base' in kwargs and (isinstance(kwargs['base'], Command) or isinstance(kwargs['base'], RCCNCommand)):
|
396
|
+
self.add_to_service(kwargs['base'].system)
|
398
397
|
|
399
398
|
def add_to_service(self, service):
|
400
|
-
if not any(command.name == 'base' for command in service.commands):
|
401
|
-
|
399
|
+
if not 'base' in self.init_kwargs and not any(command.name == 'base' for command in service.commands):
|
400
|
+
print("RCCN-Information: Command \'"+self.init_kwargs['name']+"\' doesn\'t have a base argument and no base command was found in service \'"+service.name+"\'.\nStandard base command will be used with system = \'"+service.name+"\' and type = "+str(service.service_id)+".")
|
401
|
+
self.init_kwargs['base'] = Command(
|
402
402
|
system=service,
|
403
403
|
name='base',
|
404
404
|
abstract=True,
|
405
405
|
base='/PUS/pus-tc',
|
406
406
|
assignments={'type': service.service_id}
|
407
407
|
)
|
408
|
-
|
408
|
+
elif not 'base' in self.init_kwargs and any(command.name == 'base' for command in service.commands):
|
409
|
+
print("RCCN-Information: Command \'"+self.init_kwargs['name']+"\' doesn\'t have a \'base\' argument. Existing base command for service \'"+service.name+"\' will be used.")
|
410
|
+
self.init_kwargs['base'] = next(command for command in service.commands if command.name == 'base')
|
409
411
|
if 'system' in self.init_kwargs and isinstance(self.init_kwargs['system'], Service):
|
410
412
|
super().__init__(*self.init_args, **self.init_kwargs)
|
411
413
|
else:
|
412
414
|
super().__init__(system=service, *self.init_args, **self.init_kwargs)
|
413
415
|
self.assignments['apid'] = self.system.system.apid
|
416
|
+
self.struct_name = self.name + 'Args'
|
414
417
|
|
415
418
|
|
416
419
|
def find_and_replace_keywords(self, text, text_modules_path):
|
@@ -432,8 +435,10 @@ class RCCNCommand(Command):
|
|
432
435
|
command_var_translation = {
|
433
436
|
'<<VAR_COMMAND_NAME_UCASE>>': lambda: pascalcase(self.name),
|
434
437
|
'<<VAR_COMMAND_NAME>>': lambda: self.name,
|
438
|
+
'<<VAR_COMMAND_STRUCT_NAME>>': lambda: self.struct_name,
|
435
439
|
'<<VAR_COMMAND_SUBTYPE>>': lambda: str(self.assignments['subtype']),
|
436
|
-
'<<VAR_COMMAND_STRUCT>>': lambda: self.struct_definition()
|
440
|
+
'<<VAR_COMMAND_STRUCT>>': lambda: self.struct_definition(),
|
441
|
+
'<<VAR_SHORT_DESCRIPTION>>': lambda: "\n/// " + self.short_description if self.short_description is not None else "",
|
437
442
|
}
|
438
443
|
for command_var_keyword in command_var_keywords:
|
439
444
|
if command_var_keyword in command_var_translation.keys():
|
@@ -448,9 +453,12 @@ class RCCNCommand(Command):
|
|
448
453
|
return os.path.join(self.snapshot_file_path, 'user', datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))
|
449
454
|
|
450
455
|
def struct_definition(self):
|
456
|
+
struct_definition_text = ""
|
451
457
|
if len(self.arguments) == 0:
|
452
458
|
return ''
|
453
|
-
|
459
|
+
if hasattr(self, 'long_description') and self.long_description is not None:
|
460
|
+
struct_definition_text += "/// "+str(self.long_description)+"\n"
|
461
|
+
struct_definition_text += "#[derive(BitStruct, Debug, PartialEq)]\npub struct "+pascalcase(self.struct_name)+" {\n"
|
454
462
|
ins = ""
|
455
463
|
append = ""
|
456
464
|
for argument in self.arguments:
|
@@ -463,27 +471,60 @@ class RCCNCommand(Command):
|
|
463
471
|
return struct_definition_text
|
464
472
|
|
465
473
|
class RCCNContainer(Container):
|
466
|
-
def __init__(self, base="/PUS/pus-tm", *args, **kwargs):
|
474
|
+
def __init__(self, base="/PUS/pus-tm", subtype = None, *args, **kwargs):
|
467
475
|
self.base = base
|
476
|
+
self.subtype = subtype
|
468
477
|
self.init_args = args
|
469
478
|
self.init_kwargs = kwargs
|
479
|
+
self.init_kwargs['base'] = base
|
480
|
+
self.name = kwargs['name']
|
470
481
|
if 'system' in kwargs and isinstance(kwargs['system'], Service):
|
471
482
|
self.add_to_service(kwargs['system'])
|
472
483
|
|
473
484
|
def add_to_service(self, service):
|
485
|
+
self.type = service.service_id
|
486
|
+
condition_type = None
|
487
|
+
condition_subtype = None
|
488
|
+
if 'condition' in self.init_kwargs:
|
489
|
+
for eq_expression in self.init_kwargs['condition'].expressions:
|
490
|
+
if eq_expression.ref == self.base+'/type':
|
491
|
+
condition_type = eq_expression.value
|
492
|
+
if eq_expression.ref == self.base+'/subtype':
|
493
|
+
condition_subtype = eq_expression.value
|
494
|
+
if condition_type is not None and condition_type != self.type:
|
495
|
+
print('RCCN-Warning: Container '+self.name+' has a user-defined type of '+str(eq_expression.value)+', which does\'nt match the service ID. User-defined type will be used.')
|
496
|
+
self.type = condition_type
|
497
|
+
if condition_subtype is not None and self.subtype is not None and condition_subtype != self.subtype:
|
498
|
+
print('RCCN-Warning: Container '+self.name+' has an ambiguous user-defined subtype. \'subtype\' argument should match the \'condition\' argument.')
|
499
|
+
elif condition_subtype is not None:
|
500
|
+
self.subtype = condition_subtype
|
501
|
+
elif self.subtype is not None and not 'condition' in self.init_kwargs:
|
502
|
+
self.init_kwargs['condition'] = AndExpression(
|
503
|
+
EqExpression(self.base+'/type', self.type),
|
504
|
+
EqExpression(self.base+'/subtype', self.subtype)
|
505
|
+
)
|
506
|
+
else:
|
507
|
+
raise ValueError('RCCN-Error: Container '+self.name+' has no \'condition\' argument and condition could not be created due to a missing \'subtype\' argument.')
|
508
|
+
|
474
509
|
if 'system' in self.init_kwargs and isinstance(self.init_kwargs['system'], Service):
|
475
510
|
super().__init__(*self.init_args, **self.init_kwargs)
|
476
511
|
else:
|
477
512
|
super().__init__(system=service, *self.init_args, **self.init_kwargs)
|
478
513
|
|
479
514
|
def generate_rccn_telemetry(self):
|
480
|
-
rccn_telemetry_text = "
|
515
|
+
rccn_telemetry_text = ""
|
516
|
+
if hasattr(self, 'short_description') and self.short_description is not None:
|
517
|
+
rccn_telemetry_text += "/// "+str(self.short_description)+"\n"
|
518
|
+
rccn_telemetry_text += "#[derive(ServiceTelemetry, BitStruct, Debug)]\n"
|
519
|
+
if hasattr(self, 'subtype') and self.subtype is not None:
|
520
|
+
rccn_telemetry_text += "#[subtype("+str(self.subtype)+")]\n"
|
521
|
+
rccn_telemetry_text += "pub struct " + self.name + " {\n"
|
481
522
|
insert, append = ["",""]
|
482
523
|
for parameter_entry in self.entries:
|
483
524
|
par_def = rust_type_definition(parameter_entry.parameter)
|
484
525
|
insert += par_def[0]
|
485
526
|
append += par_def[1]
|
486
527
|
rccn_telemetry_text += insert
|
487
|
-
rccn_telemetry_text += "}\n"
|
528
|
+
rccn_telemetry_text += "}\n\n"
|
488
529
|
rccn_telemetry_text += append
|
489
530
|
return rccn_telemetry_text
|
@@ -11,4 +11,7 @@ futures = "0.3.31"
|
|
11
11
|
rccn_usr = { version = "0.1.0", path = "../rccn_usr" }
|
12
12
|
satrs = "0.2.1"
|
13
13
|
spacepackets = "0.12.0"
|
14
|
-
tokio = "1.41.1"
|
14
|
+
tokio = "1.41.1"
|
15
|
+
env_logger = { version = "0.11.7", default-features = false, features = ["color", "humantime"] }
|
16
|
+
num-derive = "0.4"
|
17
|
+
num-traits = "0.2"
|
@@ -1 +1 @@
|
|
1
|
-
use
|
1
|
+
use <<VAR_SERVICE_NAME>>::service::<<VAR_SERVICE_NAME_UCASE>>;
|
@@ -21,7 +21,7 @@ impl <<VAR_SERVICE_NAME_UCASE>> {
|
|
21
21
|
impl PusService for <<VAR_SERVICE_NAME_UCASE>> {
|
22
22
|
type CommandT = command::Command;
|
23
23
|
|
24
|
-
fn handle_tc(&mut self, tc: AcceptedTc, cmd: Self::CommandT) -> AcceptanceResult {
|
24
|
+
fn handle_tc(&mut self, mut tc: AcceptedTc, cmd: Self::CommandT) -> AcceptanceResult {
|
25
25
|
println!("PUS-Service: Command received.");
|
26
26
|
match cmd {
|
27
27
|
<<COMMAND_MODULE_MATCH_CMD>>
|
rccn_gen/utils.py
CHANGED
@@ -133,7 +133,9 @@ def rust_type_definition(pymdb_data_instance, parent_name="MyStruct"):
|
|
133
133
|
pymdb_data_instance.name = singular_name
|
134
134
|
print("RCCN-Gen: Information: An unnamed "+base_type+" has been named \""+pascalcase(pymdb_data_instance.name)+"\" in the generated RCCN code.")
|
135
135
|
sc_instance_name = snakecase(pymdb_data_instance.name)
|
136
|
-
|
136
|
+
definition_text = ["",""]
|
137
|
+
if pymdb_data_instance.short_description is not None:
|
138
|
+
definition_text[0] += ("\n\t/// "+str(pymdb_data_instance.short_description)+"\n")
|
137
139
|
if data_type == 'IntegerDataType':
|
138
140
|
if pymdb_data_instance.encoding is None or pymdb_data_instance.encoding.bits is None:
|
139
141
|
raw_bit_number = 8
|
@@ -143,42 +145,50 @@ def rust_type_definition(pymdb_data_instance, parent_name="MyStruct"):
|
|
143
145
|
raw_bit_number_str = str(raw_bit_number)
|
144
146
|
eng_bit_number = engineering_bit_number(raw_bit_number)
|
145
147
|
eng_bit_number_str = str(eng_bit_number)
|
146
|
-
definition_text
|
148
|
+
definition_text[0] += "\t#[bits("+raw_bit_number_str+")]\n"
|
147
149
|
if pymdb_data_instance.signed:
|
148
150
|
definition_text[0] += ("\tpub "+sc_instance_name+": i"+eng_bit_number_str+",\n")
|
149
151
|
else:
|
150
152
|
definition_text[0] += ("\tpub "+sc_instance_name+": u"+eng_bit_number_str+",\n")
|
151
|
-
definition_text.append("")
|
152
153
|
|
153
154
|
elif data_type == 'BooleanDataType':
|
154
|
-
definition_text
|
155
|
-
definition_text.append("")
|
155
|
+
definition_text[0] += ("\t#[bits(1)]\n\tpub "+sc_instance_name+": bool,\n")
|
156
156
|
|
157
157
|
elif data_type == 'StringDataType':
|
158
|
-
definition_text
|
158
|
+
definition_text[0] += "\t#[null_terminated]\n\tpub "+sc_instance_name+": String,\n"
|
159
159
|
|
160
160
|
elif data_type == 'ArrayDataType':
|
161
161
|
definition_text = rust_type_definition(pymdb_data_instance.data_type, parent_name=pymdb_data_instance.name)
|
162
162
|
definition_text[0] = definition_text[0].replace(': ', ': Vec<').replace(',\n', '>,\n')
|
163
|
+
if pymdb_data_instance.short_description is not None:
|
164
|
+
definition_text[0] = "\n\t/// "+pymdb_data_instance.short_description+"\n"+definition_text[0]
|
165
|
+
if pymdb_data_instance.long_description is not None:
|
166
|
+
definition_text[1] = "/// "+pymdb_data_instance.long_description+"\n" + definition_text[1]
|
163
167
|
|
164
168
|
elif data_type == 'EnumeratedDataType':
|
165
|
-
definition_text
|
166
|
-
definition_text.
|
169
|
+
definition_text[0] += "\t#[bits("+str(pymdb_data_instance.encoding.bits)+")]\n"
|
170
|
+
definition_text[0] += "\tpub "+pymdb_data_instance.name+": "+pascalcase(pymdb_data_instance.name)+",\n"
|
171
|
+
definition_text[1] += ("#[derive(FromPrimative, ToPrimative, Debug)]\npub enum "+pascalcase(pymdb_data_instance.name)+" {\n")
|
167
172
|
for choice in pymdb_data_instance.choices:
|
168
173
|
definition_text[1] += "\t"+str(choice[1])+" = "+str(choice[0])+",\n"
|
169
|
-
definition_text[1] += "}\n"
|
174
|
+
definition_text[1] += "}\n\n"
|
175
|
+
if pymdb_data_instance.long_description is not None:
|
176
|
+
definition_text[1] = "/// "+pymdb_data_instance.long_description+"\n" + definition_text[1]
|
170
177
|
|
171
178
|
elif data_type == 'AggregateDataType':
|
172
179
|
struct_name = pascalcase(pymdb_data_instance.name)
|
173
|
-
definition_text
|
174
|
-
|
180
|
+
definition_text[0] += "\tpub "+sc_instance_name+": "+struct_name+",\n"
|
181
|
+
if pymdb_data_instance.long_description is not None:
|
182
|
+
definition_text[1] += "\t/// "+pymdb_data_instance.long_description+"\n"
|
183
|
+
definition_text[1] += ("#[derive(FromPrimative, ToPrimative, Debug)]\n")
|
184
|
+
definition_text[1] += ("pub struct "+struct_name+" {\n")
|
175
185
|
insert, append = ["",""]
|
176
186
|
for member in pymdb_data_instance.members:
|
177
187
|
mem_def = rust_type_definition(member, parent_name=pymdb_data_instance.name)
|
178
188
|
insert += mem_def[0]
|
179
189
|
append += mem_def[1]
|
180
190
|
definition_text[1] += insert
|
181
|
-
definition_text[1] += "}\n"
|
191
|
+
definition_text[1] += "}\n\n"
|
182
192
|
definition_text[1] += append
|
183
193
|
else:
|
184
194
|
definition_text = ["\t// Please implement datatype "+data_type+" here.\n", ""]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: rccn_gen
|
3
|
-
Version: 1.0
|
3
|
+
Version: 1.1.0
|
4
4
|
Summary: A python based generator for RACCOON OS source files in Rust from yamcs-pymdb config files.
|
5
5
|
Project-URL: Homepage, https://gitlab.com/rccn/pymdb_code_generation
|
6
6
|
Project-URL: Issues, https://gitlab.com/rccn/pymdb_code_generation/issues
|
@@ -16,19 +16,18 @@ Description-Content-Type: text/markdown
|
|
16
16
|
|
17
17
|
# RCCN Code Generator
|
18
18
|
This generator is used to generate Rust files to deploy on the RACCOON OS satellite based on the pymdb config files used to generate the ground station XTCE files.
|
19
|
+
|
20
|
+
To see whats new, see the [CHANGELOG](CHANGELOG.md).
|
19
21
|
## Setup
|
20
|
-
- Pull the repo
|
21
22
|
- Set up a virtual python environment with `python3` and activate:
|
22
23
|
```zsh
|
23
24
|
python -m venv .venv
|
24
25
|
source .venv/bin/activate
|
25
26
|
```
|
26
|
-
- Install
|
27
|
+
- Install with `pip install rccn-gen`
|
27
28
|
|
28
29
|
## Using the Generator
|
29
30
|
The generator is based on [`pymdb`](https://github.com/yamcs/pymdb) and uses the same structure. Where `pymdb` gives the user freedom in defining systems, subsystems and their respective relations, the definitions for rust code generation is more restricted. For the rust generation, the user is bound to the following classes:
|
30
|
-
- Application,
|
31
|
-
- Service, and
|
32
31
|
- `Application`,
|
33
32
|
- `Service`, and
|
34
33
|
- `RCCNCommand`.
|
@@ -53,7 +52,13 @@ A service may be defined with the following command.
|
|
53
52
|
```python
|
54
53
|
service = Service(name="ExampleService", system=app, service_id = 131)
|
55
54
|
```
|
56
|
-
|
55
|
+
Or like this:
|
56
|
+
```python
|
57
|
+
service = Service(name="ExampleService", service_id = 131)
|
58
|
+
app.add_service(service)
|
59
|
+
```
|
60
|
+
|
61
|
+
It has the obligatory arguments **name** and **system**. The system corresponds to the application where the service is associated to. Note that each service has one associated app. A service cannot be associated to more than one app. You may think of the Application-Service-Command structure as a mathematical tree, where merging branches are not allowed. However, you can create multiple instances of the same service and associate them to different applications, or create multiple identical command instances and associate them to different services.
|
57
62
|
|
58
63
|
### RCCNCommand
|
59
64
|
An RCCNCommand can be defined with the following statement.
|
@@ -65,7 +70,33 @@ RCCNCommand(
|
|
65
70
|
arguments=[StringArgument("name", encoding=StringEncoding())],
|
66
71
|
)
|
67
72
|
```
|
68
|
-
|
73
|
+
|
74
|
+
Or like this:
|
75
|
+
```python
|
76
|
+
my_command = RCCNCommand(
|
77
|
+
assignments={"subtype": 2},
|
78
|
+
name="StopProcess",
|
79
|
+
arguments=[StringArgument("name", encoding=StringEncoding())],
|
80
|
+
)
|
81
|
+
service.add_command(my_command)
|
82
|
+
```
|
83
|
+
|
84
|
+
The only obligatory arguments are **name** and a **subtype assignment**, like shown in the example. The connection to a service can also be achieved with base commands, where every base command must be unique to a service. For example:
|
85
|
+
|
86
|
+
```python
|
87
|
+
base_cmd = RCCNCommand(
|
88
|
+
system=service,
|
89
|
+
assignments={"type": service.service_id},
|
90
|
+
name="base",
|
91
|
+
base="/PUS/pus-tc"
|
92
|
+
)
|
93
|
+
my_command = RCCNCommand(
|
94
|
+
base=base_cmd,
|
95
|
+
assignments={"subtype": 2},
|
96
|
+
name="StopProcess",
|
97
|
+
arguments=[StringArgument("name", encoding=StringEncoding())],
|
98
|
+
)
|
99
|
+
```
|
69
100
|
|
70
101
|
## Output
|
71
102
|
From the python configuration, the `main.rs`, `service.rs`, `command.rs`, `mod.rs`, `Cargo.toml` and `telemetry.rs` files are generated and are structured accordingly:
|
@@ -1,19 +1,19 @@
|
|
1
1
|
rccn_gen/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
2
2
|
rccn_gen/__init__.py,sha256=rBnqIw3uQk-uBbRh9VnungoTRSr2V0Bqos32xFZ44Eo,168
|
3
|
-
rccn_gen/systems.py,sha256=
|
4
|
-
rccn_gen/utils.py,sha256=
|
5
|
-
rccn_gen/text_modules/cargo_toml/cargo.txt,sha256=
|
3
|
+
rccn_gen/systems.py,sha256=a_ylpOnHQL-RSL16HSjPZgonf4wGXiakNsvZcnq-5P8,30079
|
4
|
+
rccn_gen/utils.py,sha256=VKnTC2hrgMyLdneksAifnqEgXO27zLQJ9x5igaF35rE,8269
|
5
|
+
rccn_gen/text_modules/cargo_toml/cargo.txt,sha256=AYjSo3WJE7lhOcJaiNgXP9Y-DXHDIFIt6p42rDTVNVE,427
|
6
6
|
rccn_gen/text_modules/command/command.txt,sha256=8Y-uJilhFLoinftIbn7uKfia9LLMZno2LkoDJ-4Y-9M,345
|
7
|
-
rccn_gen/text_modules/command/command_module_enum.txt,sha256=
|
7
|
+
rccn_gen/text_modules/command/command_module_enum.txt,sha256=35sBlAV_CzQw95Uf2dNynrYOxVD2tT2XWfEvS4Zx_KY,121
|
8
8
|
rccn_gen/text_modules/command/command_module_struct.txt,sha256=FT7Ke0uOVxWYpGC_oj9zafr1ahrH-nf0nSxQje6kToY,22
|
9
|
-
rccn_gen/text_modules/main/main.txt,sha256=
|
10
|
-
rccn_gen/text_modules/main/service_module_import_service.txt,sha256=
|
9
|
+
rccn_gen/text_modules/main/main.txt,sha256=t8lAYNCgxY8XHHGt8lVeZC103O1YLEY82UoTZ2U7S2I,446
|
10
|
+
rccn_gen/text_modules/main/service_module_import_service.txt,sha256=BYPvt2VrTV4yjt7SSAPYKzvQOBIqeDQsMzgzTQ8XmZY,62
|
11
11
|
rccn_gen/text_modules/main/service_module_mod_service.txt,sha256=guvXFdV_-YezhTD_PWA-Z0tL8ReSZc0rh3RuWraJnQE,25
|
12
12
|
rccn_gen/text_modules/main/service_module_register_service.txt,sha256=4EIsgaxDLh51u0WjXfy7Xgo-6UFTdb4Nh2O4J7uFjS0,115
|
13
13
|
rccn_gen/text_modules/mod/mod.txt,sha256=BF8LablBE4ddutdl5m0prvpvLdBRejueVOujkyrLe7I,52
|
14
14
|
rccn_gen/text_modules/service/command_module_match_cmd.txt,sha256=eVGo6ltuerG37rVxpXtL-JYuLyLW4c0i6NXb5g1_U-A,89
|
15
|
-
rccn_gen/text_modules/service/service.txt,sha256=
|
15
|
+
rccn_gen/text_modules/service/service.txt,sha256=qTxoOD5i7wH4yFiDn13rOJW9hIZyACA8W3m6UABe22U,695
|
16
16
|
rccn_gen/text_modules/telemetry/telemetry.txt,sha256=Re1d3BfpyXT_CEe7jJzLF3MARik0-J-K98K85iPOE40,193
|
17
|
-
rccn_gen-1.0.
|
18
|
-
rccn_gen-1.0.
|
19
|
-
rccn_gen-1.0.
|
17
|
+
rccn_gen-1.1.0.dist-info/METADATA,sha256=O6tvxJsBHrtdX0kxFW9j7MU_oSFGW0CAVD_9Mi_WCnk,8924
|
18
|
+
rccn_gen-1.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
19
|
+
rccn_gen-1.1.0.dist-info/RECORD,,
|
File without changes
|