stinger-ipc 0.0.9__tar.gz → 0.0.25__tar.gz
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.
- {stinger_ipc-0.0.9/stinger_ipc.egg-info → stinger_ipc-0.0.25}/PKG-INFO +3 -2
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/pyproject.toml +5 -3
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25/stinger_ipc.egg-info}/PKG-INFO +3 -2
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stinger_ipc.egg-info/SOURCES.txt +7 -1
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stinger_ipc.egg-info/requires.txt +2 -1
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/asyncapi.py +3 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/components.py +61 -10
- stinger_ipc-0.0.25/stingeripc/schema/schema.yaml +240 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/examples/client_main.cpp.jinja2 +18 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/include/broker.hpp.jinja2 +18 -10
- stinger_ipc-0.0.25/stingeripc/templates/cpp/include/client.hpp.jinja2 +130 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/include/ibrokerconnection.hpp.jinja2 +24 -4
- stinger_ipc-0.0.25/stingeripc/templates/cpp/include/property_structs.hpp.jinja2 +48 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/include/server.hpp.jinja2 +5 -1
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/include/structs.hpp.jinja2 +2 -0
- stinger_ipc-0.0.25/stingeripc/templates/cpp/partials/args.jinja2 +11 -0
- stinger_ipc-0.0.25/stingeripc/templates/cpp/partials/deserialize.jinja2 +42 -0
- stinger_ipc-0.0.25/stingeripc/templates/cpp/partials/serialize.jinja2 +18 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/src/broker.cpp.jinja2 +46 -24
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/src/client.cpp.jinja2 +109 -36
- stinger_ipc-0.0.25/stingeripc/templates/cpp/src/property_structs.cpp.jinja2 +25 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/src/server.cpp.jinja2 +17 -25
- stinger_ipc-0.0.25/stingeripc/templates/cpp/src/structs.cpp.jinja2 +13 -0
- stinger_ipc-0.0.25/stingeripc/templates/html/app.js.jinja2 +226 -0
- stinger_ipc-0.0.25/stingeripc/templates/html/index.html.jinja2 +131 -0
- stinger_ipc-0.0.25/stingeripc/templates/html/styles.css.jinja2 +322 -0
- stinger_ipc-0.0.25/stingeripc/templates/markdown/index.md.jinja2 +356 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/client/src/lib.rs.jinja2 +24 -5
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/server/examples/server.rs.jinja2 +59 -23
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/server/src/lib.rs.jinja2 +78 -55
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/tools/cli.py +33 -7
- stinger_ipc-0.0.25/stingeripc/tools/cpp_generator.py +90 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/tools/rust_generator.py +1 -1
- stinger_ipc-0.0.9/stingeripc/templates/cpp/include/client.hpp.jinja2 +0 -61
- stinger_ipc-0.0.9/stingeripc/templates/cpp/include/property_structs.hpp.jinja2 +0 -10
- stinger_ipc-0.0.9/stingeripc/templates/html/app.js.jinja2 +0 -125
- stinger_ipc-0.0.9/stingeripc/templates/html/index.html.jinja2 +0 -43
- stinger_ipc-0.0.9/stingeripc/templates/html/styles.css.jinja2 +0 -187
- stinger_ipc-0.0.9/stingeripc/templates/markdown/index.md.jinja2 +0 -215
- stinger_ipc-0.0.9/stingeripc/templates/rust/payloads/src/handler.rs.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/LICENSE +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/README.md +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/setup.cfg +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stinger_ipc.egg-info/dependency_links.txt +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stinger_ipc.egg-info/entry_points.txt +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stinger_ipc.egg-info/top_level.txt +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/__init__.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/args.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/connection.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/exceptions.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/interface.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/lang_symb.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/CMakeLists.txt.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/examples/server_main.cpp.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/include/enums.hpp.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/include/return_types.hpp.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/python/__init__.py.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/python/client.py.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/python/connection.py.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/python/interface_types.py.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/python/method_codes.py.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/python/pyproject.toml.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/python/server.py.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/Cargo.toml.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/client/Cargo.toml.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/client/examples/client.rs.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/payloads/Cargo.toml.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/payloads/examples/pub_and_recv.rs.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/payloads/src/lib.rs.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/payloads/src/payloads.rs.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/rust/server/Cargo.toml.jinja2 +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/tools/__init__.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/tools/markdown_generator.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/tools/python_generator.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/topic.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/tests/test_args.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/tests/test_enum.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/tests/test_examples.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/tests/test_interface.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/tests/test_signal.py +0 -0
- {stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/tests/test_topics.py +0 -0
@@ -1,11 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: stinger-ipc
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.25
|
4
4
|
Summary: Tools to create code to do IPC over MQTT
|
5
5
|
Requires-Python: >=3.12
|
6
6
|
Description-Content-Type: text/markdown
|
7
7
|
License-File: LICENSE
|
8
|
-
Requires-Dist: jacobs-jinja-too>=0.2.
|
8
|
+
Requires-Dist: jacobs-jinja-too>=0.2.5
|
9
|
+
Requires-Dist: jacobs-json-schema>=0.4.2
|
9
10
|
Requires-Dist: packaging>=25.0
|
10
11
|
Requires-Dist: pydantic>=2.11.7
|
11
12
|
Requires-Dist: pyyaml>=6.0.2
|
@@ -1,11 +1,12 @@
|
|
1
1
|
[project]
|
2
2
|
name = "stinger-ipc"
|
3
|
-
version = "0.0.
|
3
|
+
version = "0.0.25"
|
4
4
|
description = "Tools to create code to do IPC over MQTT"
|
5
5
|
readme = "README.md"
|
6
6
|
requires-python = ">=3.12"
|
7
7
|
dependencies = [
|
8
|
-
"jacobs-jinja-too>=0.2.
|
8
|
+
"jacobs-jinja-too>=0.2.5",
|
9
|
+
"jacobs-json-schema>=0.4.2",
|
9
10
|
"packaging>=25.0",
|
10
11
|
"pydantic>=2.11.7",
|
11
12
|
"pyyaml>=6.0.2",
|
@@ -38,7 +39,8 @@ packages = ["stingeripc", "stingeripc.tools"]
|
|
38
39
|
|
39
40
|
[tool.setuptools.package-data]
|
40
41
|
stingeripc = [
|
41
|
-
"templates/**/*.jinja2"
|
42
|
+
"templates/**/*.jinja2",
|
43
|
+
"schema/schema.yaml",
|
42
44
|
]
|
43
45
|
|
44
46
|
[project.scripts]
|
@@ -1,11 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: stinger-ipc
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.25
|
4
4
|
Summary: Tools to create code to do IPC over MQTT
|
5
5
|
Requires-Python: >=3.12
|
6
6
|
Description-Content-Type: text/markdown
|
7
7
|
License-File: LICENSE
|
8
|
-
Requires-Dist: jacobs-jinja-too>=0.2.
|
8
|
+
Requires-Dist: jacobs-jinja-too>=0.2.5
|
9
|
+
Requires-Dist: jacobs-json-schema>=0.4.2
|
9
10
|
Requires-Dist: packaging>=25.0
|
10
11
|
Requires-Dist: pydantic>=2.11.7
|
11
12
|
Requires-Dist: pyyaml>=6.0.2
|
@@ -16,6 +16,7 @@ stingeripc/exceptions.py
|
|
16
16
|
stingeripc/interface.py
|
17
17
|
stingeripc/lang_symb.py
|
18
18
|
stingeripc/topic.py
|
19
|
+
stingeripc/schema/schema.yaml
|
19
20
|
stingeripc/templates/cpp/CMakeLists.txt.jinja2
|
20
21
|
stingeripc/templates/cpp/examples/client_main.cpp.jinja2
|
21
22
|
stingeripc/templates/cpp/examples/server_main.cpp.jinja2
|
@@ -27,9 +28,14 @@ stingeripc/templates/cpp/include/property_structs.hpp.jinja2
|
|
27
28
|
stingeripc/templates/cpp/include/return_types.hpp.jinja2
|
28
29
|
stingeripc/templates/cpp/include/server.hpp.jinja2
|
29
30
|
stingeripc/templates/cpp/include/structs.hpp.jinja2
|
31
|
+
stingeripc/templates/cpp/partials/args.jinja2
|
32
|
+
stingeripc/templates/cpp/partials/deserialize.jinja2
|
33
|
+
stingeripc/templates/cpp/partials/serialize.jinja2
|
30
34
|
stingeripc/templates/cpp/src/broker.cpp.jinja2
|
31
35
|
stingeripc/templates/cpp/src/client.cpp.jinja2
|
36
|
+
stingeripc/templates/cpp/src/property_structs.cpp.jinja2
|
32
37
|
stingeripc/templates/cpp/src/server.cpp.jinja2
|
38
|
+
stingeripc/templates/cpp/src/structs.cpp.jinja2
|
33
39
|
stingeripc/templates/html/app.js.jinja2
|
34
40
|
stingeripc/templates/html/index.html.jinja2
|
35
41
|
stingeripc/templates/html/styles.css.jinja2
|
@@ -47,7 +53,6 @@ stingeripc/templates/rust/client/examples/client.rs.jinja2
|
|
47
53
|
stingeripc/templates/rust/client/src/lib.rs.jinja2
|
48
54
|
stingeripc/templates/rust/payloads/Cargo.toml.jinja2
|
49
55
|
stingeripc/templates/rust/payloads/examples/pub_and_recv.rs.jinja2
|
50
|
-
stingeripc/templates/rust/payloads/src/handler.rs.jinja2
|
51
56
|
stingeripc/templates/rust/payloads/src/lib.rs.jinja2
|
52
57
|
stingeripc/templates/rust/payloads/src/payloads.rs.jinja2
|
53
58
|
stingeripc/templates/rust/server/Cargo.toml.jinja2
|
@@ -55,6 +60,7 @@ stingeripc/templates/rust/server/examples/server.rs.jinja2
|
|
55
60
|
stingeripc/templates/rust/server/src/lib.rs.jinja2
|
56
61
|
stingeripc/tools/__init__.py
|
57
62
|
stingeripc/tools/cli.py
|
63
|
+
stingeripc/tools/cpp_generator.py
|
58
64
|
stingeripc/tools/markdown_generator.py
|
59
65
|
stingeripc/tools/python_generator.py
|
60
66
|
stingeripc/tools/rust_generator.py
|
@@ -571,6 +571,9 @@ class StingerToAsyncApi:
|
|
571
571
|
add_arg(arg_spec)
|
572
572
|
resp_msg_schema.add_value_dependency(arg_spec.name, "result", 0)
|
573
573
|
elif method_spec.return_value is not None:
|
574
|
+
assert isinstance(
|
575
|
+
method_spec.return_value, Arg
|
576
|
+
), "Method return value must be a primitive or enum"
|
574
577
|
add_arg(method_spec.return_value)
|
575
578
|
resp_msg_schema.add_value_dependency(
|
576
579
|
method_spec.return_value_name, "result", 0
|
@@ -79,6 +79,10 @@ class Arg:
|
|
79
79
|
def rust_local_type(self) -> str:
|
80
80
|
return self.rust_type
|
81
81
|
|
82
|
+
@property
|
83
|
+
def cpp_type(self) -> str:
|
84
|
+
return stringmanip.upper_camel_case(self.name)
|
85
|
+
|
82
86
|
@classmethod
|
83
87
|
def new_arg_from_stinger(
|
84
88
|
cls, arg_spec: YamlArg, stinger_spec: StingerSpec | None = None
|
@@ -107,32 +111,40 @@ class Arg:
|
|
107
111
|
if arg_spec["type"] == "enum":
|
108
112
|
if "enumName" not in arg_spec:
|
109
113
|
raise InvalidStingerStructure(f"Enum args need a 'enumName'")
|
114
|
+
if not isinstance(arg_spec["enumName"], str):
|
115
|
+
raise InvalidStingerStructure("'enumName' in arg structure must be a string")
|
110
116
|
if arg_spec["enumName"] not in stinger_spec.enums:
|
111
117
|
raise InvalidStingerStructure(
|
112
118
|
f"Enum arg '{arg_spec['enumName']}' was not found in the list of stinger spec enums"
|
113
119
|
)
|
114
|
-
|
120
|
+
enum_arg = ArgEnum(
|
115
121
|
arg_spec["name"], stinger_spec.get_interface_enum(arg_spec["enumName"])
|
116
122
|
)
|
117
123
|
if opt := arg_spec.get("optional", False):
|
118
|
-
|
119
|
-
|
120
|
-
|
124
|
+
if not isinstance(opt, bool):
|
125
|
+
raise InvalidStingerStructure("'optional' in arg structure must be a boolean")
|
126
|
+
enum_arg.optional = opt
|
127
|
+
enum_arg.try_set_description_from_spec(arg_spec)
|
128
|
+
return enum_arg
|
121
129
|
|
122
130
|
if arg_spec["type"] == "struct":
|
123
131
|
if "structName" not in arg_spec:
|
124
132
|
raise InvalidStingerStructure("Struct args need a 'structName'")
|
133
|
+
if not isinstance(arg_spec["structName"], str):
|
134
|
+
raise InvalidStingerStructure("'structName' in arg structure must be a string")
|
125
135
|
if arg_spec["structName"] not in stinger_spec.structs:
|
126
136
|
raise InvalidStingerStructure(
|
127
137
|
f"Struct arg '{arg_spec["structName"]}' was not found in the list of stinger spec structs"
|
128
138
|
)
|
129
|
-
|
139
|
+
st_arg = ArgStruct(
|
130
140
|
arg_spec["name"], stinger_spec.structs[arg_spec["structName"]]
|
131
141
|
)
|
132
142
|
if opt := arg_spec.get("optional", False):
|
133
|
-
|
134
|
-
|
135
|
-
|
143
|
+
if not isinstance(opt, bool):
|
144
|
+
raise InvalidStingerStructure("'optional' in arg structure must be a boolean")
|
145
|
+
st_arg.optional = opt
|
146
|
+
st_arg.try_set_description_from_spec(arg_spec)
|
147
|
+
return st_arg
|
136
148
|
raise RuntimeError(f"unknown arg type: {arg_spec['type']}")
|
137
149
|
|
138
150
|
@abstractmethod
|
@@ -240,6 +252,8 @@ class ArgPrimitive(Arg):
|
|
240
252
|
@property
|
241
253
|
def cpp_temp_type(self) -> str:
|
242
254
|
if self._arg_type == ArgPrimitiveType.STRING:
|
255
|
+
if self.optional:
|
256
|
+
return "boost::optional<std::string>"
|
243
257
|
return "std::string"
|
244
258
|
else:
|
245
259
|
return self.cpp_type
|
@@ -288,6 +302,10 @@ class ArgPrimitive(Arg):
|
|
288
302
|
raise InvalidStingerStructure("No 'type' in arg structure")
|
289
303
|
if "name" not in arg_spec:
|
290
304
|
raise InvalidStingerStructure("No 'name' in arg structure")
|
305
|
+
if not isinstance(arg_spec["type"], str):
|
306
|
+
raise InvalidStingerStructure("'type' in arg structure must be a string")
|
307
|
+
if not isinstance(arg_spec["name"], str):
|
308
|
+
raise InvalidStingerStructure("'name' in arg structure must be a string")
|
291
309
|
|
292
310
|
arg_primitive_type = ArgPrimitiveType.from_string(arg_spec["type"])
|
293
311
|
arg: ArgPrimitive = cls(name=arg_spec["name"], arg_type=arg_primitive_type)
|
@@ -333,6 +351,10 @@ class ArgStruct(Arg):
|
|
333
351
|
def markdown_type(self) -> str:
|
334
352
|
return f"[Struct {self._interface_struct.class_name}](#enum-{self._interface_struct.class_name})"
|
335
353
|
|
354
|
+
@property
|
355
|
+
def cpp_rapidjson_type(self) -> str:
|
356
|
+
return "Object"
|
357
|
+
|
336
358
|
def get_random_example_value(self, lang="python", seed: int = 2) -> str | None:
|
337
359
|
example_list: dict[str, str] = {
|
338
360
|
a.name: str(a.get_random_example_value(lang, seed=seed))
|
@@ -688,6 +710,8 @@ class Property(InterfaceComponent):
|
|
688
710
|
prop_obj.add_arg(new_arg)
|
689
711
|
|
690
712
|
if r_o := prop_spec.get("readOnly", False):
|
713
|
+
if not isinstance(r_o, bool):
|
714
|
+
raise InvalidStingerStructure("'readOnly' in property structure must be a boolean")
|
691
715
|
prop_obj._read_only = r_o
|
692
716
|
|
693
717
|
prop_obj.try_set_documentation_from_spec(prop_spec)
|
@@ -749,6 +773,11 @@ class InterfaceEnum:
|
|
749
773
|
@property
|
750
774
|
def values(self):
|
751
775
|
return self._values
|
776
|
+
|
777
|
+
def value_description(self, index: int) -> str | None:
|
778
|
+
if index < 0 or index >= len(self._value_descriptions):
|
779
|
+
return None
|
780
|
+
return self._value_descriptions[index]
|
752
781
|
|
753
782
|
@classmethod
|
754
783
|
def new_enum_from_stinger(cls, name, enum_spec: YamlIfaceEnum) -> InterfaceEnum:
|
@@ -756,7 +785,12 @@ class InterfaceEnum:
|
|
756
785
|
for enum_obj in enum_spec.get("values", []):
|
757
786
|
assert isinstance(enum_obj, dict), f"Enum values must be a dicts."
|
758
787
|
if "name" in enum_obj and isinstance(enum_obj["name"], str):
|
759
|
-
|
788
|
+
value_description = enum_obj.get("description", None)
|
789
|
+
if value_description is not None and not isinstance(value_description, str):
|
790
|
+
raise InvalidStingerStructure(
|
791
|
+
f"InterfaceEnum '{name}' item descriptions must be strings."
|
792
|
+
)
|
793
|
+
ie.add_value(enum_obj["name"], description=value_description)
|
760
794
|
else:
|
761
795
|
raise InvalidStingerStructure(
|
762
796
|
f"InterfaceEnum '{name}' items must have string names."
|
@@ -834,9 +868,14 @@ class InterfaceStruct:
|
|
834
868
|
) -> InterfaceStruct:
|
835
869
|
istruct = cls(name)
|
836
870
|
for memb in spec.get("members", []):
|
871
|
+
if not isinstance(memb, dict):
|
872
|
+
raise InvalidStingerStructure("Struct members must be dicts")
|
837
873
|
arg = Arg.new_arg_from_stinger(memb, stinger_spec=stinger_spec)
|
838
874
|
istruct.add_member(arg)
|
839
|
-
|
875
|
+
description = spec.get("description", None)
|
876
|
+
if description is not None and not isinstance(description, str):
|
877
|
+
raise InvalidStingerStructure("Struct description must be a string")
|
878
|
+
istruct._description = description
|
840
879
|
return istruct
|
841
880
|
|
842
881
|
def __str__(self) -> str:
|
@@ -948,6 +987,18 @@ class StingerSpec:
|
|
948
987
|
}
|
949
988
|
return (self._topic_creator.interface_info_topic(), info)
|
950
989
|
|
990
|
+
@property
|
991
|
+
def summary(self) -> str:
|
992
|
+
return self._summary or ""
|
993
|
+
|
994
|
+
@property
|
995
|
+
def title(self) -> str:
|
996
|
+
return self._title or self._name or ""
|
997
|
+
|
998
|
+
@property
|
999
|
+
def documentation(self) -> str:
|
1000
|
+
return self._documentation or ""
|
1001
|
+
|
951
1002
|
def add_broker(self, broker: Broker):
|
952
1003
|
assert broker is not None
|
953
1004
|
self._brokers[broker.name] = broker
|
@@ -0,0 +1,240 @@
|
|
1
|
+
$id: "https://stingeripc.peargrove.com/stingeripc.schema.yaml"
|
2
|
+
$schema: "http://json-schema.org/draft-07/schema#"
|
3
|
+
description: |
|
4
|
+
This schema is used to validate StingerIPC stinger files.
|
5
|
+
type: object
|
6
|
+
|
7
|
+
properties:
|
8
|
+
|
9
|
+
stingeripc:
|
10
|
+
type: object
|
11
|
+
properties:
|
12
|
+
version:
|
13
|
+
type: string
|
14
|
+
const: "0.0.7"
|
15
|
+
required:
|
16
|
+
- version
|
17
|
+
|
18
|
+
interface:
|
19
|
+
type: object
|
20
|
+
parameters:
|
21
|
+
name:
|
22
|
+
type: string
|
23
|
+
pattern: "[a-zA-Z0-9_]+"
|
24
|
+
maxLength: 32
|
25
|
+
description: "A short token that will be used to create class names, folder names, filenames, etc."
|
26
|
+
title:
|
27
|
+
type: string
|
28
|
+
maxLength: 64
|
29
|
+
description: "A few words that are the title for the API. Used at the top of documentation, etc. The interface name is used if not provided."
|
30
|
+
summary:
|
31
|
+
type: string
|
32
|
+
description: "A one sentence description of the service."
|
33
|
+
maxLength: 128
|
34
|
+
version:
|
35
|
+
type: string
|
36
|
+
maxLength: 32
|
37
|
+
documentation:
|
38
|
+
$ref: "#/$defs/documentation"
|
39
|
+
required:
|
40
|
+
- name
|
41
|
+
- version
|
42
|
+
|
43
|
+
brokers:
|
44
|
+
type: object
|
45
|
+
additionalProperties:
|
46
|
+
type: object
|
47
|
+
properties:
|
48
|
+
host:
|
49
|
+
type: string
|
50
|
+
port:
|
51
|
+
type: integer
|
52
|
+
protocol:
|
53
|
+
type: string
|
54
|
+
enum:
|
55
|
+
- tcp
|
56
|
+
- websockets
|
57
|
+
default: tcp
|
58
|
+
secure:
|
59
|
+
type: boolean
|
60
|
+
default: false
|
61
|
+
description:
|
62
|
+
type: string
|
63
|
+
|
64
|
+
dependentRequired:
|
65
|
+
host: ["port"]
|
66
|
+
|
67
|
+
enums:
|
68
|
+
type: object
|
69
|
+
additionalProperties:
|
70
|
+
type: object
|
71
|
+
properties:
|
72
|
+
values:
|
73
|
+
type: array
|
74
|
+
uniqueItems: true
|
75
|
+
items:
|
76
|
+
type: object
|
77
|
+
properties:
|
78
|
+
name:
|
79
|
+
type: string
|
80
|
+
required:
|
81
|
+
- name
|
82
|
+
documentation:
|
83
|
+
$ref: "#/$defs/documentation"
|
84
|
+
required:
|
85
|
+
- values
|
86
|
+
|
87
|
+
structures:
|
88
|
+
type: object
|
89
|
+
additionalProperties:
|
90
|
+
type: object
|
91
|
+
properties:
|
92
|
+
members:
|
93
|
+
$ref: "#/$defs/payload"
|
94
|
+
documentation:
|
95
|
+
$ref: "#/$defs/documentation"
|
96
|
+
required:
|
97
|
+
- members
|
98
|
+
|
99
|
+
signals:
|
100
|
+
type: object
|
101
|
+
additionalProperties:
|
102
|
+
$ref: "#/$defs/signal"
|
103
|
+
|
104
|
+
properties:
|
105
|
+
type: object
|
106
|
+
additionalProperties:
|
107
|
+
$ref: "#/$defs/property"
|
108
|
+
|
109
|
+
methods:
|
110
|
+
type: object
|
111
|
+
additionalProperties:
|
112
|
+
$ref: "#/$defs/method"
|
113
|
+
|
114
|
+
required:
|
115
|
+
- stingeripc
|
116
|
+
- interface
|
117
|
+
|
118
|
+
$defs:
|
119
|
+
|
120
|
+
documentation:
|
121
|
+
type: string
|
122
|
+
|
123
|
+
payload:
|
124
|
+
type: array
|
125
|
+
uniqueItems: true
|
126
|
+
items:
|
127
|
+
$ref: "#/$defs/arg"
|
128
|
+
|
129
|
+
genericArg:
|
130
|
+
type: object
|
131
|
+
required:
|
132
|
+
- "type"
|
133
|
+
- "name"
|
134
|
+
properties:
|
135
|
+
name:
|
136
|
+
type: string
|
137
|
+
optional:
|
138
|
+
type: boolean
|
139
|
+
default: false
|
140
|
+
description:
|
141
|
+
type: string
|
142
|
+
schema:
|
143
|
+
type: object
|
144
|
+
description: A JSON schema which further constrains the value.
|
145
|
+
|
146
|
+
primitiveArg:
|
147
|
+
properties:
|
148
|
+
type:
|
149
|
+
type: string
|
150
|
+
enum:
|
151
|
+
- float
|
152
|
+
- string
|
153
|
+
- integer
|
154
|
+
- boolean
|
155
|
+
- date
|
156
|
+
- time
|
157
|
+
- datetime
|
158
|
+
- duration
|
159
|
+
- binary
|
160
|
+
|
161
|
+
enumArg:
|
162
|
+
properties:
|
163
|
+
type:
|
164
|
+
type: string
|
165
|
+
const: "enum"
|
166
|
+
enumName:
|
167
|
+
type: string
|
168
|
+
required:
|
169
|
+
- enumName
|
170
|
+
|
171
|
+
structArg:
|
172
|
+
properties:
|
173
|
+
type:
|
174
|
+
type: string
|
175
|
+
const: "struct"
|
176
|
+
structName:
|
177
|
+
type: string
|
178
|
+
required:
|
179
|
+
- structName
|
180
|
+
|
181
|
+
listArg:
|
182
|
+
properties:
|
183
|
+
type:
|
184
|
+
type: string
|
185
|
+
const: "list"
|
186
|
+
itemType:
|
187
|
+
oneOf:
|
188
|
+
- $ref: "#/$defs/primitiveArg"
|
189
|
+
- $ref: "#/$defs/enumArg"
|
190
|
+
- $ref: "#/$defs/structArg"
|
191
|
+
required:
|
192
|
+
- itemType
|
193
|
+
|
194
|
+
arg:
|
195
|
+
oneOf:
|
196
|
+
- allOf:
|
197
|
+
- $ref: "#/$defs/genericArg"
|
198
|
+
- $ref: "#/$defs/primitiveArg"
|
199
|
+
- allOf:
|
200
|
+
- $ref: "#/$defs/genericArg"
|
201
|
+
- $ref: "#/$defs/enumArg"
|
202
|
+
- allOf:
|
203
|
+
- $ref: "#/$defs/genericArg"
|
204
|
+
- $ref: "#/$defs/structArg"
|
205
|
+
- allOf:
|
206
|
+
- $ref: "#/$defs/genericArg"
|
207
|
+
- $ref: "#/$defs/listArg"
|
208
|
+
|
209
|
+
signal:
|
210
|
+
type: object
|
211
|
+
properties:
|
212
|
+
documentation:
|
213
|
+
$ref: "#/$defs/documentation"
|
214
|
+
payload:
|
215
|
+
$ref: "#/$defs/payload"
|
216
|
+
|
217
|
+
property:
|
218
|
+
type: object
|
219
|
+
properties:
|
220
|
+
documentation:
|
221
|
+
$ref: "#/$defs/documentation"
|
222
|
+
values:
|
223
|
+
$ref: "#/$defs/payload"
|
224
|
+
readOnly:
|
225
|
+
type: boolean
|
226
|
+
default: false
|
227
|
+
required:
|
228
|
+
- values
|
229
|
+
|
230
|
+
method:
|
231
|
+
type: object
|
232
|
+
properties:
|
233
|
+
documentation:
|
234
|
+
$ref: "#/$defs/documentation"
|
235
|
+
arguments:
|
236
|
+
$ref: "#/$defs/payload"
|
237
|
+
returnValues:
|
238
|
+
$ref: "#/$defs/payload"
|
239
|
+
required:
|
240
|
+
- arguments
|
{stinger_ipc-0.0.9 → stinger_ipc-0.0.25}/stingeripc/templates/cpp/examples/client_main.cpp.jinja2
RENAMED
@@ -1,3 +1,4 @@
|
|
1
|
+
{% import 'partials/args.jinja2' as ar %}
|
1
2
|
|
2
3
|
#include <iostream>
|
3
4
|
#include <boost/chrono/chrono.hpp>
|
@@ -16,6 +17,23 @@ int main(int argc, char** argv) {
|
|
16
17
|
});
|
17
18
|
{%-endfor%}
|
18
19
|
|
20
|
+
{%- for prop_name, prop in stinger.properties.items() %}
|
21
|
+
client.register{{prop_name | UpperCamelCase}}PropertyCallback([]({{ar.methodParams(prop.arg_list)}}) {
|
22
|
+
std::cout << "Received update for {{prop_name}} property: " << {# #}
|
23
|
+
{%-for arg in prop.arg_list-%}
|
24
|
+
"{{arg.name}}=" << {%if arg.optional%} "None"{%else%}
|
25
|
+
{%-if arg.arg_type.name.lower() == 'enum'%}
|
26
|
+
{{arg.enum.name | camelCase }}Strings[static_cast<int>({{arg.name}})]
|
27
|
+
{%elif arg.arg_type.name.lower() == 'struct'-%}
|
28
|
+
"[{{arg.cpp_type}} object]"
|
29
|
+
{%-else%}{{arg.name}}{%endif%}
|
30
|
+
{%-endif%} <<
|
31
|
+
{%-if not loop.last %} " | " << {%endif%}
|
32
|
+
{%-endfor-%}
|
33
|
+
std::endl;
|
34
|
+
});
|
35
|
+
{%endfor%}
|
36
|
+
|
19
37
|
{%-for method_name, method in stinger.methods.items() %}
|
20
38
|
std::cout << "Calling {{method_name}}" << std::endl;
|
21
39
|
auto {{method_name|camelCase}}ResultFuture = client.{{method_name | camelCase}}({%for arg in method.arg_list%}{{arg.get_random_example_value('c++')}}{%if not loop.last%}, {%endif%}{%endfor%});
|
@@ -51,21 +51,24 @@ public:
|
|
51
51
|
const std::string& payload,
|
52
52
|
unsigned qos,
|
53
53
|
bool retain,
|
54
|
-
|
55
|
-
boost::optional<std::string> optResponseTopic,
|
56
|
-
boost::optional<MethodResultCode> optResultCode);
|
54
|
+
const MqttProperties& properties);
|
57
55
|
|
58
56
|
/*! Subscribe to a topic.
|
59
57
|
* \param topic the subscription topic.
|
60
58
|
* \param qos an MQTT quality of service value between 0 and 2 inclusive.
|
59
|
+
* \return the MQTT subscription ID.
|
61
60
|
*/
|
62
|
-
virtual
|
61
|
+
virtual int Subscribe(const std::string& topic, int qos);
|
63
62
|
|
64
63
|
/*! Add a function that is called on the receipt of a message.
|
65
64
|
* Many callbacks can be added, and each will be called in the order in which the callbacks were added.
|
66
65
|
* \param cb the callback function.
|
67
66
|
*/
|
68
|
-
virtual void AddMessageCallback(const std::function<void(
|
67
|
+
virtual void AddMessageCallback(const std::function<void(
|
68
|
+
const std::string&,
|
69
|
+
const std::string&,
|
70
|
+
const MqttProperties&
|
71
|
+
)>& cb);
|
69
72
|
|
70
73
|
/*! Determines if a topic string matches a subscription topic.
|
71
74
|
* \param topic a topic to match against a subscription.
|
@@ -99,20 +102,25 @@ private:
|
|
99
102
|
|
100
103
|
struct MqttSubscription
|
101
104
|
{
|
102
|
-
MqttSubscription(const std::string& topic, int qos) :
|
105
|
+
MqttSubscription(const std::string& topic, int qos, int subscriptionId) : topic(topic), qos(qos), subscriptionId(subscriptionId) {}
|
103
106
|
~MqttSubscription() = default;
|
104
|
-
std::string
|
105
|
-
int
|
106
|
-
int
|
107
|
+
std::string topic;
|
108
|
+
int qos;
|
109
|
+
int subscriptionId;
|
107
110
|
};
|
108
111
|
|
109
112
|
mosquitto *_mosq;
|
110
113
|
std::string _host;
|
111
114
|
int _port;
|
112
115
|
std::string _clientId;
|
116
|
+
int _nextSubscriptionId = 1;
|
113
117
|
std::queue<MqttSubscription> _subscriptions;
|
114
118
|
boost::mutex _mutex;
|
115
|
-
std::vector<std::function<void(
|
119
|
+
std::vector<std::function<void(
|
120
|
+
const std::string&,
|
121
|
+
const std::string&,
|
122
|
+
const MqttProperties&
|
123
|
+
)>> _messageCallbacks;
|
116
124
|
std::queue<MqttMessage> _msgQueue;
|
117
125
|
std::map<int, std::shared_ptr<boost::promise<bool>>> _sendMessages;
|
118
126
|
};
|