@voxgig/sdkgen 4.8.2 → 4.9.0

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.
Files changed (407) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/action/doctor.d.ts +1 -0
  3. package/dist/action/doctor.js +50 -2
  4. package/dist/action/doctor.js.map +1 -1
  5. package/dist/helpers/naming.js +4 -2
  6. package/dist/helpers/naming.js.map +1 -1
  7. package/dist/tsconfig.tsbuildinfo +1 -1
  8. package/model/sdkgen.aon +21 -0
  9. package/package.json +1 -1
  10. package/project/.sdk/model/feature/secrets.aon +120 -18
  11. package/project/.sdk/model/target/c.aon +10 -0
  12. package/project/.sdk/model/target/clojure.aon +13 -0
  13. package/project/.sdk/model/target/cpp.aon +10 -0
  14. package/project/.sdk/model/target/csharp.aon +9 -0
  15. package/project/.sdk/model/target/dart.aon +10 -0
  16. package/project/.sdk/model/target/elixir.aon +9 -0
  17. package/project/.sdk/model/target/go.aon +13 -0
  18. package/project/.sdk/model/target/java.aon +9 -0
  19. package/project/.sdk/model/target/js.aon +7 -0
  20. package/project/.sdk/model/target/kotlin.aon +9 -0
  21. package/project/.sdk/model/target/lean.aon +17 -0
  22. package/project/.sdk/model/target/lua.aon +8 -0
  23. package/project/.sdk/model/target/ocaml.aon +9 -0
  24. package/project/.sdk/model/target/perl.aon +8 -0
  25. package/project/.sdk/model/target/php.aon +8 -0
  26. package/project/.sdk/model/target/py.aon +13 -0
  27. package/project/.sdk/model/target/rb.aon +8 -0
  28. package/project/.sdk/model/target/rust.aon +10 -0
  29. package/project/.sdk/model/target/scala.aon +21 -2
  30. package/project/.sdk/model/target/swift.aon +18 -0
  31. package/project/.sdk/model/target/ts.aon +13 -0
  32. package/project/.sdk/model/target/zig.aon +9 -0
  33. package/project/.sdk/src/cmp/clojure/Package_clojure.ts +9 -2
  34. package/project/.sdk/src/cmp/cpp/Gitignore_cpp.ts +3 -0
  35. package/project/.sdk/src/cmp/dart/Test_dart.ts +2 -0
  36. package/project/.sdk/src/cmp/elixir/Package_elixir.ts +4 -1
  37. package/project/.sdk/src/cmp/go/Config_go.ts +59 -2
  38. package/project/.sdk/src/cmp/go/Main_go.ts +8 -2
  39. package/project/.sdk/src/cmp/java/Test_java.ts +6 -5
  40. package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +6 -5
  41. package/project/.sdk/src/cmp/lean/Package_lean.ts +23 -0
  42. package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +1 -0
  43. package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +1 -0
  44. package/project/.sdk/src/cmp/ocaml/Gitignore_ocaml.ts +1 -0
  45. package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +7 -3
  46. package/project/.sdk/src/cmp/py/Config_py.ts +82 -1
  47. package/project/.sdk/src/cmp/py/Main_py.ts +44 -0
  48. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +2 -0
  49. package/project/.sdk/src/cmp/swift/Main_swift.ts +10 -0
  50. package/project/.sdk/src/cmp/swift/Package_swift.ts +13 -1
  51. package/project/.sdk/src/cmp/ts/Config_ts.ts +42 -17
  52. package/project/.sdk/src/cmp/ts/fragment/Config.data.fragment.ts +13 -1
  53. package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +13 -1
  54. package/project/.sdk/src/cmp/zig/Package_zig.ts +15 -11
  55. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +3 -3
  56. package/project/.sdk/src/cmp/zig/fragment/EntityListOp.fragment.zig +3 -3
  57. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +3 -3
  58. package/project/.sdk/src/cmp/zig/utility_zig.ts +50 -1
  59. package/project/.sdk/tm/c/Makefile +38 -3
  60. package/project/.sdk/tm/c/tests/omni_resolver.h +361 -0
  61. package/project/.sdk/tm/c/tests/omni_smoke_test.c +237 -0
  62. package/project/.sdk/tm/c/tests/primary_corpus_test.c +205 -284
  63. package/project/.sdk/tm/c/tests/struct_corpus_test.c +292 -212
  64. package/project/.sdk/tm/c/tests/vendor/omni/json.c +811 -0
  65. package/project/.sdk/tm/c/tests/vendor/omni/omni.h +240 -0
  66. package/project/.sdk/tm/c/tests/vendor/omni/runner.c +940 -0
  67. package/project/.sdk/tm/c/tests/vendor/omni/util.c +351 -0
  68. package/project/.sdk/tm/c/utility/struct/utility.c +7 -2
  69. package/project/.sdk/tm/clojure/test/sdk/test/omni.clj +401 -0
  70. package/project/.sdk/tm/clojure/test/sdk/test/omni_smoke.clj +81 -0
  71. package/project/.sdk/tm/clojure/test/sdk/test/primary.clj +92 -58
  72. package/project/.sdk/tm/clojure/test/sdk/test/struct_corpus.clj +122 -149
  73. package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +8 -3
  74. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/json.clj +145 -0
  75. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/runner.clj +445 -0
  76. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/util.clj +145 -0
  77. package/project/.sdk/tm/cpp/Makefile +5 -1
  78. package/project/.sdk/tm/cpp/test/omni_resolver.hpp +473 -0
  79. package/project/.sdk/tm/cpp/test/omni_smoke_test.cpp +209 -0
  80. package/project/.sdk/tm/cpp/test/primary_utility_test.cpp +243 -184
  81. package/project/.sdk/tm/cpp/test/runner_support.hpp +68 -181
  82. package/project/.sdk/tm/cpp/test/struct_corpus_test.cpp +183 -56
  83. package/project/.sdk/tm/cpp/test/vendor/omni/json.hpp +406 -0
  84. package/project/.sdk/tm/cpp/test/vendor/omni/omni.hpp +751 -0
  85. package/project/.sdk/tm/cpp/test/vendor/omni/util.hpp +256 -0
  86. package/project/.sdk/tm/cpp/utility/pipeline.hpp +7 -1
  87. package/project/.sdk/tm/csharp/test/OmniResolver.cs +491 -0
  88. package/project/.sdk/tm/csharp/test/OmniSmokeTest.cs +106 -0
  89. package/project/.sdk/tm/csharp/test/PrimaryUtilityTest.cs +299 -316
  90. package/project/.sdk/tm/csharp/test/Runner.cs +104 -269
  91. package/project/.sdk/tm/csharp/test/StructUtilityTest.cs +535 -724
  92. package/project/.sdk/tm/csharp/test/vendor/omni/Runner.cs +864 -0
  93. package/project/.sdk/tm/csharp/test/vendor/omni/Util.cs +347 -0
  94. package/project/.sdk/tm/csharp/utility/MakeSpec.cs +3 -1
  95. package/project/.sdk/tm/csharp/utility/PrepareMethod.cs +6 -1
  96. package/project/.sdk/tm/csharp/utility/struct/Struct.cs +21 -5
  97. package/project/.sdk/tm/dart/test/omni.dart +520 -0
  98. package/project/.sdk/tm/dart/test/omni_smoke_test.dart +143 -0
  99. package/project/.sdk/tm/dart/test/primary_test.dart +86 -28
  100. package/project/.sdk/tm/dart/test/struct_test.dart +438 -11
  101. package/project/.sdk/tm/dart/test/vendor/omni/omni.dart +7 -0
  102. package/project/.sdk/tm/dart/test/vendor/omni/runner.dart +653 -0
  103. package/project/.sdk/tm/dart/test/vendor/omni/util.dart +232 -0
  104. package/project/.sdk/tm/elixir/Makefile +11 -3
  105. package/project/.sdk/tm/elixir/test/omni_smoke_test.exs +117 -0
  106. package/project/.sdk/tm/elixir/test/primary_utility_test.exs +341 -16
  107. package/project/.sdk/tm/elixir/test/struct_corpus_test.exs +554 -9
  108. package/project/.sdk/tm/elixir/test/support/omni.ex +377 -0
  109. package/project/.sdk/tm/elixir/test/vendor/omni/json.ex +122 -0
  110. package/project/.sdk/tm/elixir/test/vendor/omni/runner.ex +623 -0
  111. package/project/.sdk/tm/elixir/test/vendor/omni/util.ex +187 -0
  112. package/project/.sdk/tm/go/core/context.go +32 -16
  113. package/project/.sdk/tm/go/feature/secrets/plugin/capability.go +261 -0
  114. package/project/.sdk/tm/go/feature/secrets/plugin/catalog.go +78 -0
  115. package/project/.sdk/tm/go/feature/secrets/plugin/config.go +652 -0
  116. package/project/.sdk/tm/go/feature/secrets/plugin/depend.go +250 -0
  117. package/project/.sdk/tm/go/feature/secrets/plugin/env.go +194 -0
  118. package/project/.sdk/tm/go/feature/secrets/plugin/export.go +80 -0
  119. package/project/.sdk/tm/go/feature/secrets/plugin/graph.go +238 -0
  120. package/project/.sdk/tm/go/feature/secrets/plugin/host.go +1575 -0
  121. package/project/.sdk/tm/go/feature/secrets/plugin/order.go +248 -0
  122. package/project/.sdk/tm/go/feature/secrets/plugin/point.go +184 -0
  123. package/project/.sdk/tm/go/feature/secrets/plugin/ref.go +123 -0
  124. package/project/.sdk/tm/go/feature/secrets/plugin/resolve.go +79 -0
  125. package/project/.sdk/tm/go/feature/secrets/plugin/types.go +296 -0
  126. package/project/.sdk/tm/go/feature/secrets/plugin/util.go +87 -0
  127. package/project/.sdk/tm/go/feature/secrets/plugin/version.go +161 -0
  128. package/project/.sdk/tm/go/feature/secrets/plugins/aws/aws.go +292 -0
  129. package/project/.sdk/tm/go/feature/secrets/plugins/aws/sigv4.go +201 -0
  130. package/project/.sdk/tm/go/feature/secrets/plugins/azuresecrets/azuresecrets.go +187 -0
  131. package/project/.sdk/tm/go/feature/secrets/plugins/boru/boru.go +184 -0
  132. package/project/.sdk/tm/go/feature/secrets/plugins/doppler/doppler.go +114 -0
  133. package/project/.sdk/tm/go/feature/secrets/plugins/gcpsecrets/gcpsecrets.go +156 -0
  134. package/project/.sdk/tm/go/feature/secrets/plugins/hashicorp/hashicorp.go +208 -0
  135. package/project/.sdk/tm/go/feature/secrets/plugins/httpjson/httpjson.go +241 -0
  136. package/project/.sdk/tm/go/feature/secrets/plugins/infisical/infisical.go +150 -0
  137. package/project/.sdk/tm/go/feature/secrets/plugins/onepassword/onepassword.go +152 -0
  138. package/project/.sdk/tm/go/feature/secrets/plugins/secretspec/secretspec.go +143 -0
  139. package/project/.sdk/tm/go/feature/secrets/sekreto/addr.go +120 -0
  140. package/project/.sdk/tm/go/feature/secrets/sekreto/providers.go +442 -0
  141. package/project/.sdk/tm/go/feature/secrets/sekreto/sekreto.go +714 -0
  142. package/project/.sdk/tm/go/feature/secrets_feature.go +675 -0
  143. package/project/.sdk/tm/go/src/feature/secrets/.gitkeep +0 -0
  144. package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +799 -0
  145. package/project/.sdk/tm/go/test/omni/omni.go +902 -0
  146. package/project/.sdk/tm/go/test/omni/util.go +381 -0
  147. package/project/.sdk/tm/go/test/omniresolver_test.go +748 -0
  148. package/project/.sdk/tm/go/test/omnismoke_test.go +112 -0
  149. package/project/.sdk/tm/go/test/primary_utility_test.go +123 -191
  150. package/project/.sdk/tm/go/test/struct_utility_test.go +323 -16
  151. package/project/.sdk/tm/go/test/testsupport_test.go +294 -0
  152. package/project/.sdk/tm/go/utility/make_options.go +8 -1
  153. package/project/.sdk/tm/go/utility/prepare_method.go +5 -1
  154. package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +2 -2
  155. package/project/.sdk/tm/java/test/OmniResolver.java +355 -0
  156. package/project/.sdk/tm/java/test/OmniSmokeTest.java +99 -0
  157. package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +254 -280
  158. package/project/.sdk/tm/java/test/RunnerSupport.java +9 -194
  159. package/project/.sdk/tm/java/test/StructCorpusTest.java +119 -42
  160. package/project/.sdk/tm/java/test/vendor/omni/Json.java +287 -0
  161. package/project/.sdk/tm/java/test/vendor/omni/Runner.java +851 -0
  162. package/project/.sdk/tm/java/test/vendor/omni/Util.java +322 -0
  163. package/project/.sdk/tm/java/utility/MakeSpec.java +3 -1
  164. package/project/.sdk/tm/java/utility/PrepareMethod.java +5 -5
  165. package/project/.sdk/tm/java/utility/struct/Struct.java +17 -4
  166. package/project/.sdk/tm/js/src/utility/StructUtility.js +3 -3
  167. package/project/.sdk/tm/js/test/omni.js +251 -0
  168. package/project/.sdk/tm/js/test/omni.test.js +105 -0
  169. package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +6 -2
  170. package/project/.sdk/tm/js/test/utility/StructUtility.test.js +27 -2
  171. package/project/.sdk/tm/js/test/vendor/omni/index.js +77 -0
  172. package/project/.sdk/tm/js/test/vendor/omni/runner.js +628 -0
  173. package/project/.sdk/tm/js/test/vendor/omni/util.js +229 -0
  174. package/project/.sdk/tm/kotlin/core/Utility.kt +1 -1
  175. package/project/.sdk/tm/kotlin/test/OmniResolver.kt +343 -0
  176. package/project/.sdk/tm/kotlin/test/OmniSmokeTest.kt +100 -0
  177. package/project/.sdk/tm/kotlin/test/PrimaryUtilityTest.kt +244 -262
  178. package/project/.sdk/tm/kotlin/test/RunnerSupport.kt +9 -178
  179. package/project/.sdk/tm/kotlin/test/StructCorpusTest.kt +121 -32
  180. package/project/.sdk/tm/kotlin/test/vendor/omni/Json.kt +264 -0
  181. package/project/.sdk/tm/kotlin/test/vendor/omni/Runner.kt +615 -0
  182. package/project/.sdk/tm/kotlin/test/vendor/omni/Util.kt +139 -0
  183. package/project/.sdk/tm/kotlin/utility/MakeSpecUrl.kt +6 -3
  184. package/project/.sdk/tm/kotlin/utility/Prepare.kt +6 -6
  185. package/project/.sdk/tm/kotlin/utility/struct/Struct.kt +18 -2
  186. package/project/.sdk/tm/lean/Makefile +12 -5
  187. package/project/.sdk/tm/lean/src/SdkUtility.lean +14 -1
  188. package/project/.sdk/tm/lean/test/OmniResolver.lean +358 -0
  189. package/project/.sdk/tm/lean/test/OmniSmoke.lean +174 -0
  190. package/project/.sdk/tm/lean/test/StructCorpus.lean +245 -574
  191. package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +155 -291
  192. package/project/.sdk/tm/lean/test/vendor/omni/Omni.lean +997 -0
  193. package/project/.sdk/tm/lua/test/omni.lua +456 -0
  194. package/project/.sdk/tm/lua/test/omni_smoke_test.lua +103 -0
  195. package/project/.sdk/tm/lua/test/primary_utility_test.lua +250 -509
  196. package/project/.sdk/tm/lua/test/struct_utility_test.lua +161 -70
  197. package/project/.sdk/tm/lua/test/vendor/omni/json.lua +268 -0
  198. package/project/.sdk/tm/lua/test/vendor/omni/regex.lua +385 -0
  199. package/project/.sdk/tm/lua/test/vendor/omni/runner.lua +641 -0
  200. package/project/.sdk/tm/lua/test/vendor/omni/util.lua +282 -0
  201. package/project/.sdk/tm/lua/utility/prepare_method.lua +5 -1
  202. package/project/.sdk/tm/lua/utility/struct/regex.lua +663 -0
  203. package/project/.sdk/tm/lua/utility/struct/struct.lua +660 -420
  204. package/project/.sdk/tm/ocaml/Makefile +37 -12
  205. package/project/.sdk/tm/ocaml/test/omni_resolver.ml +284 -0
  206. package/project/.sdk/tm/ocaml/test/omni_smoke_test.ml +169 -0
  207. package/project/.sdk/tm/ocaml/test/primary_utility_test.ml +84 -100
  208. package/project/.sdk/tm/ocaml/test/struct_corpus.ml +225 -201
  209. package/project/.sdk/tm/ocaml/test/vendor/omni/omni.ml +1157 -0
  210. package/project/.sdk/tm/perl/lib/Voxgig/Struct.pm +88 -12
  211. package/project/.sdk/tm/perl/t/omni.pm +647 -0
  212. package/project/.sdk/tm/perl/t/omni_smoke.t +87 -0
  213. package/project/.sdk/tm/perl/t/primary_utility.t +189 -487
  214. package/project/.sdk/tm/perl/t/struct_utility.t +455 -389
  215. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Runner.pm +649 -0
  216. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Util.pm +253 -0
  217. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni.pm +24 -0
  218. package/project/.sdk/tm/perl/utility/prepare_method.pm +7 -2
  219. package/project/.sdk/tm/php/test/Omni.php +691 -0
  220. package/project/.sdk/tm/php/test/OmniSmokeTest.php +93 -0
  221. package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +210 -571
  222. package/project/.sdk/tm/php/test/StructUtilityTest.php +320 -342
  223. package/project/.sdk/tm/php/test/vendor/omni/Runner.php +644 -0
  224. package/project/.sdk/tm/php/test/vendor/omni/Util.php +283 -0
  225. package/project/.sdk/tm/php/utility/MakeSpec.php +10 -3
  226. package/project/.sdk/tm/php/utility/PrepareBody.php +7 -1
  227. package/project/.sdk/tm/php/utility/PrepareMethod.php +6 -2
  228. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/__init__.py +36 -0
  229. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/capability.py +141 -0
  230. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/catalog.py +50 -0
  231. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/config.py +333 -0
  232. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/depend.py +198 -0
  233. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/env.py +147 -0
  234. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/export.py +52 -0
  235. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/graph.py +139 -0
  236. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/host.py +1053 -0
  237. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/order.py +171 -0
  238. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/point.py +95 -0
  239. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/ref.py +116 -0
  240. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/resolve.py +59 -0
  241. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/types.py +87 -0
  242. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/version.py +112 -0
  243. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/__init__.py +76 -0
  244. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/addr.py +116 -0
  245. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/aws.py +192 -0
  246. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/azuresecrets.py +120 -0
  247. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/boru.py +140 -0
  248. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/doppler.py +62 -0
  249. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.py +101 -0
  250. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/hashicorp.py +151 -0
  251. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/httpjson.py +115 -0
  252. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/infisical.py +90 -0
  253. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/onepassword.py +101 -0
  254. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/secretspec.py +119 -0
  255. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/sigv4.py +125 -0
  256. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/providers.py +211 -0
  257. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/sekreto.py +475 -0
  258. package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +467 -0
  259. package/project/.sdk/tm/py/pkg/utility/prepare_method.py +5 -1
  260. package/project/.sdk/tm/py/pkg/utility/voxgig_struct/__init__.py +0 -2
  261. package/project/.sdk/tm/py/pkg/utility/voxgig_struct/voxgig_struct.py +780 -529
  262. package/project/.sdk/tm/py/src/feature/secrets/.gitkeep +0 -0
  263. package/project/.sdk/tm/py/test/feature/__init__.py +0 -0
  264. package/project/.sdk/tm/py/test/feature/secrets/__init__.py +0 -0
  265. package/project/.sdk/tm/py/test/feature/secrets/test_secrets.py +337 -0
  266. package/project/.sdk/tm/py/test/omni.py +415 -0
  267. package/project/.sdk/tm/py/test/test_omni_smoke.py +74 -0
  268. package/project/.sdk/tm/py/test/test_primary_utility.py +144 -668
  269. package/project/.sdk/tm/py/test/test_struct_utility.py +74 -27
  270. package/project/.sdk/tm/py/test/voxgig_omni/__init__.py +62 -0
  271. package/project/.sdk/tm/py/test/voxgig_omni/runner.py +580 -0
  272. package/project/.sdk/tm/py/test/voxgig_omni/util.py +252 -0
  273. package/project/.sdk/tm/rb/test/omni.rb +505 -0
  274. package/project/.sdk/tm/rb/test/omni_smoke_test.rb +72 -0
  275. package/project/.sdk/tm/rb/test/primary_utility_test.rb +174 -560
  276. package/project/.sdk/tm/rb/test/struct_utility_test.rb +13 -7
  277. package/project/.sdk/tm/rb/test/vendor/omni/runner.rb +493 -0
  278. package/project/.sdk/tm/rb/test/vendor/omni/util.rb +199 -0
  279. package/project/.sdk/tm/rb/test/vendor/omni/voxgig_omni.rb +15 -0
  280. package/project/.sdk/tm/rb/utility/prepare_method.rb +5 -1
  281. package/project/.sdk/tm/rust/tests/common/mod.rs +19 -242
  282. package/project/.sdk/tm/rust/tests/omni_resolver/mod.rs +888 -0
  283. package/project/.sdk/tm/rust/tests/omni_smoke_test.rs +286 -0
  284. package/project/.sdk/tm/rust/tests/primary_utility_test.rs +318 -312
  285. package/project/.sdk/tm/rust/tests/struct_utility_test.rs +66 -28
  286. package/project/.sdk/tm/rust/tests/vendor/omni/json.rs +412 -0
  287. package/project/.sdk/tm/rust/tests/vendor/omni/mod.rs +38 -0
  288. package/project/.sdk/tm/rust/tests/vendor/omni/regex.rs +392 -0
  289. package/project/.sdk/tm/rust/tests/vendor/omni/runner.rs +1001 -0
  290. package/project/.sdk/tm/rust/tests/vendor/omni/util.rs +161 -0
  291. package/project/.sdk/tm/rust/utility/prepare_method.rs +5 -1
  292. package/project/.sdk/tm/scala/Makefile +16 -6
  293. package/project/.sdk/tm/scala/sdktest/OmniResolver.scala +497 -0
  294. package/project/.sdk/tm/scala/sdktest/OmniSmoke.scala +192 -0
  295. package/project/.sdk/tm/scala/sdktest/PrimaryCorpus.scala +47 -19
  296. package/project/.sdk/tm/scala/sdktest/StructCorpus.scala +0 -0
  297. package/project/.sdk/tm/scala/sdktest/vendor/omni/Json.scala +229 -0
  298. package/project/.sdk/tm/scala/sdktest/vendor/omni/Runner.scala +552 -0
  299. package/project/.sdk/tm/scala/sdktest/vendor/omni/Util.scala +104 -0
  300. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Constants.swift +10 -0
  301. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Inject.swift +28 -5
  302. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Injection.swift +5 -1
  303. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Minor.swift +4 -1
  304. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Validate.swift +15 -5
  305. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Prepare.swift +6 -1
  306. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/OmniResolver.swift +474 -0
  307. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/OmniSmokeTest.swift +107 -0
  308. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +141 -178
  309. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/Runner.swift +17 -113
  310. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/StructUtilityTest.swift +295 -446
  311. package/project/.sdk/tm/swift/Tests/vendor/omni/Json.swift +364 -0
  312. package/project/.sdk/tm/swift/Tests/vendor/omni/Runner.swift +730 -0
  313. package/project/.sdk/tm/swift/Tests/vendor/omni/Util.swift +162 -0
  314. package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +7 -0
  315. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Capability.ts +148 -0
  316. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Catalog.ts +55 -0
  317. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Config.ts +344 -0
  318. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Depend.ts +205 -0
  319. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Env.ts +138 -0
  320. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Export.ts +46 -0
  321. package/project/.sdk/tm/ts/src/feature/secrets/plugin/FeatureHost.ts +349 -0
  322. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Graph.ts +181 -0
  323. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Host.ts +1132 -0
  324. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Order.ts +177 -0
  325. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Point.ts +119 -0
  326. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Ref.ts +102 -0
  327. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Resolve.ts +61 -0
  328. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Types.ts +112 -0
  329. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Version.ts +100 -0
  330. package/project/.sdk/tm/ts/src/feature/secrets/plugin/index.ts +37 -0
  331. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +163 -30
  332. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +27 -22
  333. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/aws.ts +26 -36
  334. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/azuresecrets.ts +19 -21
  335. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/boru.ts +36 -17
  336. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/doppler.ts +14 -21
  337. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/gcpsecrets.ts +27 -27
  338. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/hashicorp.ts +25 -39
  339. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/httpjson.ts +99 -0
  340. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/infisical.ts +14 -16
  341. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/onepassword.ts +15 -22
  342. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/secretspec.ts +98 -0
  343. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{Sigv4.ts → plugins/sigv4.ts} +7 -6
  344. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +97 -23
  345. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/builtin.ts +37 -0
  346. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +4 -17
  347. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +4 -16
  348. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +11 -25
  349. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +6 -23
  350. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +106 -39
  351. package/project/.sdk/tm/ts/src/utility/StructUtility.ts +3 -3
  352. package/project/.sdk/tm/ts/test/omni.ts +104 -32
  353. package/project/.sdk/tm/ts/test/utility/StructUtility.test.ts +27 -0
  354. package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +32 -5
  355. package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +2 -2
  356. package/project/.sdk/tm/ts/test/vendor/omni/index.ts +2 -2
  357. package/project/.sdk/tm/zig/Makefile +15 -1
  358. package/project/.sdk/tm/zig/build.zig +23 -5
  359. package/project/.sdk/tm/zig/core/helpers.zig +52 -11
  360. package/project/.sdk/tm/zig/core/mem.zig +17 -1
  361. package/project/.sdk/tm/zig/core/utility.zig +23 -19
  362. package/project/.sdk/tm/zig/feature/audit.zig +2 -2
  363. package/project/.sdk/tm/zig/feature/cache.zig +2 -2
  364. package/project/.sdk/tm/zig/feature/debug.zig +5 -5
  365. package/project/.sdk/tm/zig/feature/netsim.zig +2 -2
  366. package/project/.sdk/tm/zig/feature/paging.zig +2 -2
  367. package/project/.sdk/tm/zig/feature/proxy.zig +15 -8
  368. package/project/.sdk/tm/zig/feature/streaming.zig +5 -5
  369. package/project/.sdk/tm/zig/feature/support.zig +3 -3
  370. package/project/.sdk/tm/zig/feature/telemetry.zig +5 -5
  371. package/project/.sdk/tm/zig/feature/test.zig +10 -5
  372. package/project/.sdk/tm/zig/test/fh.zig +10 -10
  373. package/project/.sdk/tm/zig/test/gotcha_test.zig +5 -5
  374. package/project/.sdk/tm/zig/test/omniresolver.zig +515 -0
  375. package/project/.sdk/tm/zig/test/omnismoke_test.zig +284 -0
  376. package/project/.sdk/tm/zig/test/pipeline_test.zig +8 -8
  377. package/project/.sdk/tm/zig/test/primary_utility_test.zig +145 -155
  378. package/project/.sdk/tm/zig/test/struct_corpus.zig +264 -187
  379. package/project/.sdk/tm/zig/test/vendor/omni/omni.zig +1314 -0
  380. package/project/.sdk/tm/zig/test/vendor/omni/regex.zig +446 -0
  381. package/project/.sdk/tm/zig/utility/voxgigstruct/regex.zig +7 -4
  382. package/project/.sdk/tm/zig/utility/voxgigstruct/struct.zig +356 -157
  383. package/project/sdkgen-package.json +1 -1
  384. package/src/action/doctor.ts +66 -2
  385. package/src/helpers/naming.ts +4 -2
  386. package/project/.sdk/tm/c/tests/runner.h +0 -274
  387. package/project/.sdk/tm/cpp/test/struct_runner.hpp +0 -314
  388. package/project/.sdk/tm/csharp/test/StructRunner.cs +0 -276
  389. package/project/.sdk/tm/dart/test/runner.dart +0 -406
  390. package/project/.sdk/tm/dart/test/struct_corpus.dart +0 -531
  391. package/project/.sdk/tm/elixir/test/support/struct_corpus.ex +0 -1088
  392. package/project/.sdk/tm/go/test/runner_test.go +0 -629
  393. package/project/.sdk/tm/go/test/struct_runner_test.go +0 -1094
  394. package/project/.sdk/tm/java/test/StructRunner.java +0 -281
  395. package/project/.sdk/tm/js/test/runner.js +0 -387
  396. package/project/.sdk/tm/kotlin/test/StructRunner.kt +0 -177
  397. package/project/.sdk/tm/lua/test/struct_runner.lua +0 -602
  398. package/project/.sdk/tm/ocaml/test/corpus_runner.ml +0 -185
  399. package/project/.sdk/tm/perl/t/struct_runner.pm +0 -275
  400. package/project/.sdk/tm/php/test/StructRunner.php +0 -275
  401. package/project/.sdk/tm/py/test/struct_runner.py +0 -411
  402. package/project/.sdk/tm/rb/test/struct_runner.rb +0 -309
  403. package/project/.sdk/tm/rust/tests/struct_runner/mod.rs +0 -424
  404. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/Registry.ts +0 -90
  405. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/http.ts +0 -66
  406. package/project/.sdk/tm/ts/test/vendor/omni/compat.ts +0 -188
  407. package/project/.sdk/tm/zig/test/struct_runner.zig +0 -464
@@ -0,0 +1,888 @@
1
+ // The corpus test runner: vendored @voxgig/omni driven through its NATIVE
2
+ // API (`omni::runner::make_runner` / `RunPack::runsetflags_args`), presented
3
+ // to the corpus suites in the struct-runner shape they already use
4
+ // (`run.spec`, `run.set`, `run.run_set`, `run.run_set_fallible`,
5
+ // `run.passed`, `run.failures`). No compat shim is vendored: the adapter
6
+ // below IS the whole bridge, per language, per the vendor-tag rollout
7
+ // (docs/design/vendor-tag-rollout.md, Decision 4). It supersedes the whole
8
+ // of the retired `tests/struct_runner/mod.rs` and the corpus ENGINE half of
9
+ // `tests/common/mod.rs` (`runset`/`runset_named`/`match_deep`/`match_string`
10
+ // went with it; that file's SUPPORT half — env, sdk-test-control, ctx
11
+ // construction, the fh harness — is retained under its own name, so the
12
+ // emitted call sites did not move).
13
+ //
14
+ // It is the Rust peer of tm/csharp/test/OmniResolver.cs,
15
+ // tm/java/test/OmniResolver.java and
16
+ // tm/swift/Tests/ProjectNameSDKTests/OmniResolver.swift, and it follows the
17
+ // bridge voxgig/struct's own rust corpus harness already uses
18
+ // (struct/rust/corpus/tests/omni.rs) — the portable answer for a statically
19
+ // typed port with no reflection: omni's `Provider` is closure-based, so
20
+ // nothing in omni ever has to name this SDK's types.
21
+ //
22
+ // Rust-specific decisions, each load-bearing:
23
+ //
24
+ // 1. TWO VALUE MODELS, ONE CONVERSION PAIR. omni's `Json` and the SDK's
25
+ // `voxgigstruct::Value` are different enums, so every crossing is an
26
+ // explicit `tostruct` / `toomni`. `Json::Absent` <-> `Value::Noval` and
27
+ // `Json::Null` <-> `Value::Null` keep the two no-value states the corpus
28
+ // distinguishes apart — which is also why Rust needs neither go's
29
+ // `novalargs` spec rewrite nor lua/php's compat shim for the corpus's
30
+ // zero-argument entries (an entry with no `in`/`args`/`ctx` arrives as
31
+ // one `Json::Absent`, and becomes exactly this port's own NOVAL).
32
+ //
33
+ // 2. ARGUMENTS ARE WRITTEN BACK. `SubjectArgs` (`Fn(&mut [Json])`) is the
34
+ // channel omni provides for a subject that MUTATES its arguments, which
35
+ // `match: {args: ...}` then asserts on — `struct/minor/setpath` and
36
+ // `struct/merge/integrity` turn on it. Decision 1 handed the subject a
37
+ // CONVERTED COPY, so every subject here runs through `runsetflags_args`
38
+ // and the wrapper converts the (possibly mutated) `Value` arguments back
39
+ // into omni's own slice after the call. A dynamic port's shim gets this
40
+ // for free from shared object identity; Rust cannot.
41
+ //
42
+ // 3. `match: {ctx: ...}` IS RETARGETED ONTO `match: {args: {"0": ...}}`.
43
+ // The one place this port cannot follow canonical omni as written, and a
44
+ // VALUE-SEMANTICS consequence, not a choice. omni's `Json` is a plain
45
+ // enum: `resolveargs` stores `entry.ctx` and `args[0]` as two COPIES of
46
+ // the contextified map, and `checkresult` reads `entry.get("ctx")` for
47
+ // the ctx base — so a subject's post-call writes (decision 2) can never
48
+ // reach the copy `entry.ctx` holds, and nine `primary` entries assert
49
+ // exactly that post-call state. args[0] IS the ctx of a ctx entry (omni
50
+ // itself sets `args = [entry.get("ctx")]`), so moving the assertion from
51
+ // `ctx` to `args.0` reads the SAME map, post-call, and preserves every
52
+ // leaf: nothing is dropped, weakened or skipped. `retargetctx` below does
53
+ // that rewrite on the spec handed to the engine. Swift faces the identical
54
+ // problem and answers it identically; the upstream fix is for the Rust
55
+ // port's `drive` to re-point `entry.ctx` at the returned `args[0]`, the
56
+ // way JS object identity does implicitly — filed as a follow-up, not
57
+ // worked around by editing a vendored file.
58
+ //
59
+ // 4. NUMBERS NEED NOTHING. omni's parser reads every JSON number as `f64`
60
+ // and this port's `Value::Num` is also `f64` — unlike go/csharp/java,
61
+ // where an integral double had to be narrowed before a subject saw it.
62
+ //
63
+ // 5. KEY ORDER. omni models a map as a `BTreeMap`, which sorts; this port's
64
+ // `OrderedMap` preserves insertion order. Every map in the shared corpus
65
+ // is already in sorted key order, so the round-trip is lossless over it —
66
+ // but an out-of-order map authored later WOULD be reordered on the way
67
+ // in, and `raw_unsorted_keys` below is the tripwire that says so instead
68
+ // of failing an order-sensitive subject (`keysof`, `items`, `stringify`)
69
+ // with a mystery diff. It reads the corpus FILE with its own
70
+ // order-preserving scanner and never touches `Json`: a check fed by
71
+ // omni's parser would be comparing an already-sorted map against itself
72
+ // and could not fail. See `corpus_maps_are_in_sorted_key_order`.
73
+ //
74
+ // 7. WHAT RAN IS COUNTED, NOT WHAT WAS DECLARED. `drive` counts SUBJECT
75
+ // INVOCATIONS, not `entrycount(set)`: a number derived from the spec
76
+ // cannot tell a working engine from a disconnected one, and would read as
77
+ // evidence while proving nothing. It also compares the two and fails the
78
+ // group when they differ. `report` then refuses to pass on a group that
79
+ // is absent from the corpus, or present in the corpus but driven by
80
+ // nothing — the two ways a suite quietly stops checking.
81
+ //
82
+ // 6. FAILURES ARE ACCUMULATED, NOT RAISED. omni stops a group at its first
83
+ // bad entry and returns an `OmniError`; the struct suite reports the whole
84
+ // corpus in one panic at the end. `drive` records the message and carries
85
+ // on, so one run still names every broken GROUP.
86
+
87
+ #![allow(dead_code)]
88
+ // The vendored port re-exports its whole surface; a test crate uses part of
89
+ // it, and the rest must not warn. The attributes go on the module
90
+ // DECLARATION - a vendored file is never edited.
91
+ #![allow(unused_imports)]
92
+
93
+ #[path = "../vendor/omni/mod.rs"]
94
+ pub mod omni;
95
+
96
+ use std::collections::BTreeMap;
97
+ use std::path::PathBuf;
98
+ use std::rc::Rc;
99
+
100
+ pub use omni::json::Json;
101
+ pub use omni::runner::{Flags, OmniError, Provider, RunPack, SpecRef, Subject, SubjectArgs};
102
+ pub use omni::util::{EXISTSMARK, NULLMARK, UNDEFMARK};
103
+
104
+ use RUSTCRATE::utility::voxgigstruct::ordered_map::OrderedMap;
105
+ use RUSTCRATE::utility::voxgigstruct::value::Value;
106
+ use RUSTCRATE::utility::voxgigstruct::InjectDef;
107
+ use RUSTCRATE::ProjectNameError;
108
+
109
+ // ---------------------------------------------------------------------------
110
+ // The two value models (decision 1)
111
+ // ---------------------------------------------------------------------------
112
+
113
+ /// omni's model -> this SDK's.
114
+ pub fn tostruct(val: &Json) -> Value {
115
+ match val {
116
+ Json::Absent => Value::Noval,
117
+ Json::Null => Value::Null,
118
+ Json::Bool(flag) => Value::Bool(*flag),
119
+ Json::Num(num) => Value::Num(*num),
120
+ Json::Str(text) => Value::Str(text.clone()),
121
+ Json::List(items) => Value::list(items.iter().map(tostruct).collect()),
122
+ Json::Map(entries) => {
123
+ let mut map = OrderedMap::new();
124
+ for (key, entry) in entries.iter() {
125
+ map.insert(key.clone(), tostruct(entry));
126
+ }
127
+ Value::map(map)
128
+ }
129
+ }
130
+ }
131
+
132
+ /// This SDK's model -> omni's.
133
+ ///
134
+ /// `Value::Func` has no JSON shape at all. It reaches here only when a corpus
135
+ /// entry puts a callable in data (`get_elem` with a callable `alt`, `$APPLY`,
136
+ /// a user `$FORMAT`), and in every such case the corpus asserts on what the
137
+ /// call RETURNED, not on the callable. `Json::Absent` is the honest answer:
138
+ /// it is what omni's own model says about a value that is not JSON, and
139
+ /// omni's `fixjson` then renders it as NULLMARK under the null flag — the
140
+ /// same place the retired hand-written `fix_json` put it.
141
+ pub fn toomni(val: &Value) -> Json {
142
+ match val {
143
+ Value::Noval => Json::Absent,
144
+ Value::Null => Json::Null,
145
+ Value::Bool(flag) => Json::Bool(*flag),
146
+ Value::Num(num) => Json::Num(*num),
147
+ Value::Str(text) => Json::Str(text.clone()),
148
+ Value::List(items) => Json::List(items.borrow().iter().map(toomni).collect()),
149
+ Value::Map(entries) => {
150
+ let mut map = BTreeMap::new();
151
+ for (key, entry) in entries.borrow().iter() {
152
+ map.insert(key.clone(), toomni(entry));
153
+ }
154
+ Json::Map(map)
155
+ }
156
+ Value::Func(_) => Json::Absent,
157
+ Value::Sentinel(_) => Json::Absent,
158
+ }
159
+ }
160
+
161
+ /// The tripwire for decision 5: how many maps the raw corpus scan inspected,
162
+ /// and the first one whose keys are NOT in sorted order.
163
+ pub struct KeyOrderScan {
164
+ /// Maps inspected. Reported so a scan that read nothing cannot pass as a
165
+ /// scan that found nothing.
166
+ pub maps: usize,
167
+ /// `<dotted path>: [keys as authored]` for the first offender.
168
+ pub unsorted: Option<String>,
169
+ }
170
+
171
+ /// Scan RAW JSON TEXT for a map whose keys are not in sorted order.
172
+ ///
173
+ /// This deliberately does NOT go through `omni::runner::loadspec`: omni's
174
+ /// `Json::Map` is a `BTreeMap`, so a parse has already sorted every map and
175
+ /// the disorder this exists to catch is gone before the check can see it. A
176
+ /// tripwire fed by the thing it is watching cannot fire, so the scanner
177
+ /// below walks the file itself and keeps keys in the order they were
178
+ /// authored. `String`'s ordering is byte-lexicographic on UTF-8, which is
179
+ /// exactly the ordering a `BTreeMap<String, _>` imposes, so a sorted scan
180
+ /// means a lossless crossing.
181
+ ///
182
+ /// Panics on malformed JSON: a corpus this cannot parse must be loud, not a
183
+ /// silent zero-map pass.
184
+ pub fn raw_unsorted_keys(text: &str) -> KeyOrderScan {
185
+ let mut scan = RawScan {
186
+ src: text.as_bytes(),
187
+ pos: 0,
188
+ maps: 0,
189
+ path: Vec::new(),
190
+ unsorted: None,
191
+ };
192
+ scan.ws();
193
+ scan.value();
194
+ scan.ws();
195
+ if scan.pos != scan.src.len() {
196
+ scan.bail("trailing input after the top-level value");
197
+ }
198
+ KeyOrderScan {
199
+ maps: scan.maps,
200
+ unsorted: scan.unsorted,
201
+ }
202
+ }
203
+
204
+ /// A structure-only JSON reader: it builds no values, it only walks the text
205
+ /// and records the key order of every object it passes through.
206
+ struct RawScan<'a> {
207
+ src: &'a [u8],
208
+ pos: usize,
209
+ maps: usize,
210
+ path: Vec<String>,
211
+ unsorted: Option<String>,
212
+ }
213
+
214
+ impl<'a> RawScan<'a> {
215
+ fn bail(&self, why: &str) -> ! {
216
+ panic!(
217
+ "corpus key-order scan: {} at byte {} (path {:?})",
218
+ why,
219
+ self.pos,
220
+ self.path.join(".")
221
+ )
222
+ }
223
+
224
+ fn peek(&self) -> u8 {
225
+ if self.pos < self.src.len() {
226
+ self.src[self.pos]
227
+ } else {
228
+ 0
229
+ }
230
+ }
231
+
232
+ fn ws(&mut self) {
233
+ while self.pos < self.src.len() {
234
+ match self.src[self.pos] {
235
+ b' ' | b'\t' | b'\n' | b'\r' => self.pos += 1,
236
+ _ => break,
237
+ }
238
+ }
239
+ }
240
+
241
+ fn expect(&mut self, want: u8) {
242
+ if self.peek() != want {
243
+ self.bail(&format!("expected {:?}", want as char));
244
+ }
245
+ self.pos += 1;
246
+ }
247
+
248
+ fn value(&mut self) {
249
+ match self.peek() {
250
+ b'{' => self.object(),
251
+ b'[' => self.array(),
252
+ b'"' => {
253
+ self.string();
254
+ }
255
+ b't' => self.literal(b"true"),
256
+ b'f' => self.literal(b"false"),
257
+ b'n' => self.literal(b"null"),
258
+ b'-' | b'0'..=b'9' => self.number(),
259
+ _ => self.bail("not a JSON value"),
260
+ }
261
+ }
262
+
263
+ fn literal(&mut self, want: &[u8]) {
264
+ if self.src.len() < self.pos + want.len() || &self.src[self.pos..self.pos + want.len()] != want {
265
+ self.bail("bad literal");
266
+ }
267
+ self.pos += want.len();
268
+ }
269
+
270
+ fn number(&mut self) {
271
+ let start = self.pos;
272
+ while self.pos < self.src.len() {
273
+ match self.src[self.pos] {
274
+ b'-' | b'+' | b'.' | b'e' | b'E' | b'0'..=b'9' => self.pos += 1,
275
+ _ => break,
276
+ }
277
+ }
278
+ if start == self.pos {
279
+ self.bail("empty number");
280
+ }
281
+ }
282
+
283
+ /// A JSON string, unescaped — a key must be compared as the DECODED text,
284
+ /// which is what a `BTreeMap` would hold.
285
+ fn string(&mut self) -> String {
286
+ self.expect(b'"');
287
+ let mut out = String::new();
288
+ loop {
289
+ if self.pos >= self.src.len() {
290
+ self.bail("unterminated string");
291
+ }
292
+ let byte = self.src[self.pos];
293
+ self.pos += 1;
294
+ match byte {
295
+ b'"' => return out,
296
+ b'\\' => {
297
+ if self.pos >= self.src.len() {
298
+ self.bail("unterminated escape");
299
+ }
300
+ let esc = self.src[self.pos];
301
+ self.pos += 1;
302
+ match esc {
303
+ b'"' => out.push('"'),
304
+ b'\\' => out.push('\\'),
305
+ b'/' => out.push('/'),
306
+ b'b' => out.push('\u{8}'),
307
+ b'f' => out.push('\u{c}'),
308
+ b'n' => out.push('\n'),
309
+ b'r' => out.push('\r'),
310
+ b't' => out.push('\t'),
311
+ b'u' => {
312
+ let code = self.hex4();
313
+ // A surrogate pair is two \u escapes; the corpus has
314
+ // none, but decode them rather than mis-order one.
315
+ if (0xD800..0xDC00).contains(&code) {
316
+ if b'\\' == self.peek() {
317
+ self.pos += 1;
318
+ self.expect(b'u');
319
+ let low = self.hex4();
320
+ let joined =
321
+ 0x10000 + ((code - 0xD800) << 10) + (low - 0xDC00);
322
+ out.push(
323
+ char::from_u32(joined)
324
+ .unwrap_or_else(|| self.bail("bad surrogate pair")),
325
+ );
326
+ } else {
327
+ self.bail("lone high surrogate");
328
+ }
329
+ } else {
330
+ out.push(
331
+ char::from_u32(code)
332
+ .unwrap_or_else(|| self.bail("bad \\u escape")),
333
+ );
334
+ }
335
+ }
336
+ _ => self.bail("unknown escape"),
337
+ }
338
+ }
339
+ _ => {
340
+ // Copy the whole UTF-8 sequence, not just its lead byte.
341
+ let width = utf8width(byte);
342
+ let end = self.pos - 1 + width;
343
+ if self.src.len() < end {
344
+ self.bail("truncated UTF-8 in string");
345
+ }
346
+ match std::str::from_utf8(&self.src[self.pos - 1..end]) {
347
+ Ok(text) => out.push_str(text),
348
+ Err(_) => self.bail("invalid UTF-8 in string"),
349
+ }
350
+ self.pos = end;
351
+ }
352
+ }
353
+ }
354
+ }
355
+
356
+ fn hex4(&mut self) -> u32 {
357
+ if self.src.len() < self.pos + 4 {
358
+ self.bail("truncated \\u escape");
359
+ }
360
+ let text = std::str::from_utf8(&self.src[self.pos..self.pos + 4])
361
+ .unwrap_or_else(|_| self.bail("bad \\u escape"));
362
+ let code = u32::from_str_radix(text, 16).unwrap_or_else(|_| self.bail("bad \\u escape"));
363
+ self.pos += 4;
364
+ code
365
+ }
366
+
367
+ fn array(&mut self) {
368
+ self.expect(b'[');
369
+ self.ws();
370
+ if b']' == self.peek() {
371
+ self.pos += 1;
372
+ return;
373
+ }
374
+ let mut index = 0usize;
375
+ loop {
376
+ self.path.push(index.to_string());
377
+ self.ws();
378
+ self.value();
379
+ self.path.pop();
380
+ self.ws();
381
+ match self.peek() {
382
+ b',' => {
383
+ self.pos += 1;
384
+ index += 1;
385
+ }
386
+ b']' => {
387
+ self.pos += 1;
388
+ return;
389
+ }
390
+ _ => self.bail("expected ',' or ']'"),
391
+ }
392
+ }
393
+ }
394
+
395
+ fn object(&mut self) {
396
+ self.expect(b'{');
397
+ self.maps += 1;
398
+ let mut keys: Vec<String> = Vec::new();
399
+ self.ws();
400
+ if b'}' == self.peek() {
401
+ self.pos += 1;
402
+ self.checkorder(&keys);
403
+ return;
404
+ }
405
+ loop {
406
+ self.ws();
407
+ let key = self.string();
408
+ keys.push(key.clone());
409
+ self.ws();
410
+ self.expect(b':');
411
+ self.ws();
412
+ self.path.push(key);
413
+ self.value();
414
+ self.path.pop();
415
+ self.ws();
416
+ match self.peek() {
417
+ b',' => self.pos += 1,
418
+ b'}' => {
419
+ self.pos += 1;
420
+ self.checkorder(&keys);
421
+ return;
422
+ }
423
+ _ => self.bail("expected ',' or '}'"),
424
+ }
425
+ }
426
+ }
427
+
428
+ fn checkorder(&mut self, keys: &[String]) {
429
+ if self.unsorted.is_some() {
430
+ return;
431
+ }
432
+ let mut sorted = keys.to_vec();
433
+ sorted.sort();
434
+ if keys != sorted.as_slice() {
435
+ self.unsorted = Some(format!("{}: {:?}", self.path.join("."), keys));
436
+ }
437
+ }
438
+ }
439
+
440
+ fn utf8width(lead: u8) -> usize {
441
+ if 0xF0 <= lead {
442
+ 4
443
+ } else if 0xE0 <= lead {
444
+ 3
445
+ } else if 0xC0 <= lead {
446
+ 2
447
+ } else {
448
+ 1
449
+ }
450
+ }
451
+
452
+ // ---------------------------------------------------------------------------
453
+ // Spec access
454
+ // ---------------------------------------------------------------------------
455
+
456
+ /// The shared corpus, compiled by the project build. `CARGO_MANIFEST_DIR` is
457
+ /// the SDK's own `rust/` directory, and the corpus sits beside it.
458
+ pub fn spec_path() -> String {
459
+ let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
460
+ path.push("..");
461
+ path.push(".sdk");
462
+ path.push("test");
463
+ path.push("test.json");
464
+ path.to_string_lossy().into_owned()
465
+ }
466
+
467
+ /// The whole corpus, as omni loaded it.
468
+ pub fn corpus() -> Json {
469
+ omni::runner::loadspec(SpecRef::Path(spec_path()))
470
+ .unwrap_or_else(|err| panic!("omni: {}", err.message))
471
+ }
472
+
473
+ /// A child node by key (absent when missing).
474
+ pub fn jget(val: &Json, key: &str) -> Json {
475
+ val.get(key)
476
+ }
477
+
478
+ /// A child node by path.
479
+ pub fn jpath(val: &Json, keys: &[&str]) -> Json {
480
+ let mut current = val.clone();
481
+ for key in keys {
482
+ current = current.get(key);
483
+ }
484
+ current
485
+ }
486
+
487
+ /// How many entries a group declares.
488
+ pub fn entrycount(set: &Json) -> usize {
489
+ set.get("set").aslist().map(|list| list.len()).unwrap_or(0)
490
+ }
491
+
492
+ // ---------------------------------------------------------------------------
493
+ // The runner
494
+ // ---------------------------------------------------------------------------
495
+
496
+ /// What the runner returns for one named spec section — the struct-runner
497
+ /// shape the corpus call sites consume.
498
+ pub struct Run {
499
+ pack: RunPack,
500
+ /// The whole corpus (sections outside this one: `DEF` blocks, the
501
+ /// `primary/check` client group the struct suite drives by hand).
502
+ pub all: Json,
503
+ /// The resolved section.
504
+ pub spec: Json,
505
+ pub failures: Vec<String>,
506
+ pub passed: usize,
507
+ /// Groups absent from THIS SDK's corpus subset, named so a run reports
508
+ /// what it did not check rather than passing in silence. `report`
509
+ /// FAILS on any name here that the suite did not declare expected.
510
+ pub skipped: Vec<String>,
511
+ /// Every group label the suite ASKED for, present or absent. `report`
512
+ /// checks it against the groups the corpus actually carries, so a
513
+ /// corpus group that nothing drives is a failure rather than a silence.
514
+ pub driven: Vec<String>,
515
+ }
516
+
517
+ impl Run {
518
+ /// A runner over one named section of the shared corpus.
519
+ pub fn section(name: &str) -> Run {
520
+ Run::over(corpus(), name)
521
+ }
522
+
523
+ /// A runner over an in-memory spec — omni's own capability, which keeps
524
+ /// the smoke test free of a fixture file.
525
+ pub fn over(all: Json, name: &str) -> Run {
526
+ let runner = omni::runner::make_runner(all.clone(), Provider::default())
527
+ .unwrap_or_else(|err| panic!("omni: {}", err.message));
528
+ let pack = runner
529
+ .runner(name, None)
530
+ .unwrap_or_else(|err| panic!("omni: {}", err.message));
531
+
532
+ Run {
533
+ spec: pack.spec.clone(),
534
+ pack,
535
+ all,
536
+ failures: Vec::new(),
537
+ passed: 0,
538
+ skipped: Vec::new(),
539
+ driven: Vec::new(),
540
+ }
541
+ }
542
+
543
+ /// A named group of the resolved section.
544
+ pub fn set(&self, keys: &[&str]) -> Json {
545
+ jpath(&self.spec, keys)
546
+ }
547
+
548
+ /// Run one group whose subject cannot fail.
549
+ pub fn run_set<F>(&mut self, set: &Json, nullflag: bool, label: &str, subject: F)
550
+ where
551
+ F: FnMut(Value) -> Value + 'static,
552
+ {
553
+ let cell = Rc::new(std::cell::RefCell::new(subject));
554
+ self.drive(set, nullflag, label, move |args: &mut [Json]| {
555
+ let input = tostruct(args.first().unwrap_or(&Json::Absent));
556
+ let result = (cell.borrow_mut())(input.clone());
557
+ writeback(args, 0, &input);
558
+ Ok(toomni(&result))
559
+ });
560
+ }
561
+
562
+ /// Run one group whose subject may fail, which the corpus asserts on
563
+ /// with `err`.
564
+ pub fn run_set_fallible<F>(&mut self, set: &Json, nullflag: bool, label: &str, subject: F)
565
+ where
566
+ F: FnMut(Value) -> Result<Value, String> + 'static,
567
+ {
568
+ let cell = Rc::new(std::cell::RefCell::new(subject));
569
+ self.drive(set, nullflag, label, move |args: &mut [Json]| {
570
+ let input = tostruct(args.first().unwrap_or(&Json::Absent));
571
+ let result = (cell.borrow_mut())(input.clone());
572
+ writeback(args, 0, &input);
573
+ result.map(|val| toomni(&val))
574
+ });
575
+ }
576
+
577
+ /// Run one group whose subject takes omni's whole argument list and may
578
+ /// fail with an SDK error. This is the shape the `primary` suite needs:
579
+ /// a `ctx` entry arrives as `args[0]`, a MAP, which the call site turns
580
+ /// into a typed `Context` and writes observable state back into
581
+ /// (decisions 2 and 3).
582
+ pub fn run_set_args<F>(&mut self, set: &Json, nullflag: bool, label: &str, subject: F)
583
+ where
584
+ F: FnMut(&mut Vec<Value>) -> Result<Value, ProjectNameError> + 'static,
585
+ {
586
+ let cell = Rc::new(std::cell::RefCell::new(subject));
587
+ self.drive(set, nullflag, label, move |args: &mut [Json]| {
588
+ let mut input: Vec<Value> = args.iter().map(tostruct).collect();
589
+ let result = (cell.borrow_mut())(&mut input);
590
+ for (index, val) in input.iter().enumerate() {
591
+ writeback(args, index, val);
592
+ }
593
+ result.map(|val| toomni(&val)).map_err(|err| err.msg)
594
+ });
595
+ }
596
+
597
+ /// Hand one group to omni and record the outcome.
598
+ fn drive<F>(&mut self, set: &Json, nullflag: bool, label: &str, subject: F)
599
+ where
600
+ F: Fn(&mut [Json]) -> Result<Json, String> + 'static,
601
+ {
602
+ self.driven.push(label.to_string());
603
+
604
+ // A section this SDK's corpus subset does not carry. Named, not
605
+ // silent: `report` fails unless the suite declared this skip.
606
+ if set.isabsent() {
607
+ self.skipped.push(label.to_string());
608
+ return;
609
+ }
610
+
611
+ let flags = Flags {
612
+ null: nullflag,
613
+ name: Some(label.to_string()),
614
+ };
615
+ let count = entrycount(set);
616
+ let usespec = retargetctx(set);
617
+
618
+ // Decision 7: count SUBJECT INVOCATIONS. `entrycount` says what the
619
+ // corpus declares, which a disconnected engine would report just as
620
+ // happily; this says what actually reached a subject.
621
+ let calls = Rc::new(std::cell::Cell::new(0usize));
622
+ let seen = calls.clone();
623
+ let usesubject: SubjectArgs = Rc::new(move |args: &mut [Json]| {
624
+ seen.set(seen.get() + 1);
625
+ subject(args)
626
+ });
627
+
628
+ match self.pack.runsetflags_args(&usespec, &flags, &usesubject) {
629
+ Ok(()) => {
630
+ let ran = calls.get();
631
+ if ran != count {
632
+ self.failures.push(format!(
633
+ "{}: the engine reported success after running {} of the {} \
634
+ entries the corpus declares",
635
+ label, ran, count
636
+ ));
637
+ }
638
+ self.passed += ran;
639
+ }
640
+ Err(err) => self.failures.push(err.message.replace('\n', " | ")),
641
+ }
642
+ }
643
+
644
+ /// Every `<category>-<group>` in this section that carries a non-empty
645
+ /// `set` — the groups a suite over this section is expected to drive.
646
+ ///
647
+ /// Shape-specific: it assumes the `struct` section's two levels
648
+ /// (`<category>.<group>.set`) and the `"<category>-<group>"` labels the
649
+ /// struct suite passes to `run_set`. The `primary` section nests
650
+ /// differently (`primary.<name>.basic`) and labels its groups `<name>`,
651
+ /// so it guards zero-case runs in `runsection` instead — see
652
+ /// tests/primary_utility_test.rs.
653
+ pub fn corpus_groups(&self) -> Vec<(String, usize)> {
654
+ let mut found: Vec<(String, usize)> = Vec::new();
655
+ let categories = match self.spec.asmap() {
656
+ Some(map) => map,
657
+ None => return found,
658
+ };
659
+ for (category, node) in categories.iter() {
660
+ let groups = match node.asmap() {
661
+ Some(map) => map,
662
+ // `<category>.name` is a string and `<category>.set` an empty
663
+ // list; neither is a group.
664
+ None => continue,
665
+ };
666
+ for (name, group) in groups.iter() {
667
+ let count = entrycount(group);
668
+ if group.ismap() && 0 < count {
669
+ found.push((format!("{}-{}", category, name), count));
670
+ }
671
+ }
672
+ }
673
+ found
674
+ }
675
+
676
+ /// Fail the test with every accumulated failure, or report the count.
677
+ ///
678
+ /// `expectedskips` names the groups THIS SDK's corpus subset does not
679
+ /// carry. It is exhaustive in both directions: a group that goes absent
680
+ /// without being listed fails, and a listed group that is no longer
681
+ /// absent fails too. Without that a renamed or deleted group would take
682
+ /// its whole check count with it and the suite would still say `ok` —
683
+ /// the exact silence the shared oracle exists to prevent.
684
+ pub fn report(&self, what: &str, expectedskips: &[&str]) {
685
+ let mut problems: Vec<String> = self.failures.clone();
686
+
687
+ for label in self.skipped.iter() {
688
+ if !expectedskips.contains(&label.as_str()) {
689
+ problems.push(format!(
690
+ "{}: ABSENT from the corpus, so it ran ZERO checks — a renamed or \
691
+ deleted group. Restore it, or add it to the expected-skip list.",
692
+ label
693
+ ));
694
+ }
695
+ }
696
+ for label in expectedskips.iter() {
697
+ if !self.skipped.iter().any(|name| name == label) {
698
+ problems.push(format!(
699
+ "{}: listed as an expected skip but was not skipped — either the \
700
+ corpus now carries it (drop it from the expected-skip list) or the \
701
+ suite stopped asking for it.",
702
+ label
703
+ ));
704
+ }
705
+ }
706
+ for (label, count) in self.corpus_groups() {
707
+ if !self.driven.iter().any(|name| *name == label) {
708
+ problems.push(format!(
709
+ "{}: the corpus carries this group ({} entries) but NOTHING in this \
710
+ suite drives it — wire up a subject, or the entries are dead weight.",
711
+ label, count
712
+ ));
713
+ }
714
+ }
715
+
716
+ if !problems.is_empty() {
717
+ let total = problems.len();
718
+ let mut message = format!(
719
+ "\n{} corpus problem(s) ({} checks actually ran):\n",
720
+ total, self.passed
721
+ );
722
+ for problem in problems.iter().take(60) {
723
+ message.push_str(" - ");
724
+ message.push_str(problem);
725
+ message.push('\n');
726
+ }
727
+ if 60 < total {
728
+ message.push_str(&format!(" ... and {} more\n", total - 60));
729
+ }
730
+ panic!("{message}");
731
+ }
732
+
733
+ if !self.skipped.is_empty() {
734
+ eprintln!(
735
+ "{}: skipped (declared absent from this corpus subset): {:?}",
736
+ what, self.skipped
737
+ );
738
+ }
739
+ eprintln!("{}: {} checks passed", what, self.passed);
740
+ }
741
+ }
742
+
743
+ /// Write one converted argument back into omni's own slice (decision 2).
744
+ fn writeback(args: &mut [Json], index: usize, val: &Value) {
745
+ if let Some(slot) = args.get_mut(index) {
746
+ *slot = toomni(val);
747
+ }
748
+ }
749
+
750
+ /// Retarget `match: {ctx: ...}` onto `match: {args: {"0": ...}}` — decision 3.
751
+ /// Only when the entry HAS a ctx or args (so args[0] is that map) and the
752
+ /// check does not already assert on `args`.
753
+ fn retargetctx(testspec: &Json) -> Json {
754
+ let set = match testspec.get("set") {
755
+ Json::List(list) => list,
756
+ _ => return testspec.clone(),
757
+ };
758
+
759
+ let mut out: Vec<Json> = Vec::with_capacity(set.len());
760
+ for rawentry in set.iter() {
761
+ let check = rawentry.get("match");
762
+ if rawentry.ismap()
763
+ && check.ismap()
764
+ && check.has("ctx")
765
+ && !check.has("args")
766
+ && (rawentry.has("ctx") || rawentry.has("args"))
767
+ {
768
+ let mut newcheck = BTreeMap::new();
769
+ if let Json::Map(fields) = &check {
770
+ for (key, val) in fields.iter() {
771
+ // Drop the original leaf: it would read the stale
772
+ // pre-call copy omni keeps in `entry.ctx`.
773
+ if "ctx" != key {
774
+ newcheck.insert(key.clone(), val.clone());
775
+ }
776
+ }
777
+ }
778
+ let mut byindex = BTreeMap::new();
779
+ byindex.insert("0".to_string(), check.get("ctx"));
780
+ newcheck.insert("args".to_string(), Json::Map(byindex));
781
+
782
+ let mut entry = BTreeMap::new();
783
+ if let Json::Map(fields) = rawentry {
784
+ for (key, val) in fields.iter() {
785
+ entry.insert(key.clone(), val.clone());
786
+ }
787
+ }
788
+ entry.insert("match".to_string(), Json::Map(newcheck));
789
+ out.push(Json::Map(entry));
790
+ continue;
791
+ }
792
+ out.push(rawentry.clone());
793
+ }
794
+
795
+ let mut spec = BTreeMap::new();
796
+ if let Json::Map(fields) = testspec {
797
+ for (key, val) in fields.iter() {
798
+ spec.insert(key.clone(), val.clone());
799
+ }
800
+ }
801
+ spec.insert("set".to_string(), Json::List(out));
802
+ Json::Map(spec)
803
+ }
804
+
805
+ // ---------------------------------------------------------------------------
806
+ // Corpus-entry helpers, retained from the retired struct_runner
807
+ // ---------------------------------------------------------------------------
808
+
809
+ /// Raw field extraction from a corpus entry, in this SDK's value model:
810
+ /// preserves a stored JSON null so a field declared `null` (`{val: null}`)
811
+ /// reaches the subject as `Value::Null` and is not silently dropped.
812
+ pub fn vget(val: &Value, key: &str) -> Value {
813
+ RUSTCRATE::utility::voxgigstruct::lookup(val, &Value::str(key))
814
+ }
815
+
816
+ pub fn vget_path(val: &Value, keys: &[&str]) -> Value {
817
+ let mut current = val.clone();
818
+ for key in keys {
819
+ current = vget(&current, key);
820
+ }
821
+ current
822
+ }
823
+
824
+ pub fn as_i64_opt(val: &Value) -> Option<i64> {
825
+ match val {
826
+ Value::Num(num) => Some(*num as i64),
827
+ _ => None,
828
+ }
829
+ }
830
+
831
+ pub fn as_str_opt(val: &Value) -> Option<String> {
832
+ match val {
833
+ Value::Str(text) => Some(text.clone()),
834
+ _ => None,
835
+ }
836
+ }
837
+
838
+ pub fn b(flag: bool) -> Value {
839
+ Value::Bool(flag)
840
+ }
841
+
842
+ /// The `fixjson` of the corpus's own comparison boundary, for the handful of
843
+ /// corpus nodes that are a single `{in, out}` object rather than a `set` and
844
+ /// so never reach omni (`merge/basic`, `inject/basic`, `transform/basic`,
845
+ /// `walk/log`). omni does exactly this to everything it runs.
846
+ pub fn fix_json(val: &Value, nullflag: bool) -> Value {
847
+ tostruct(&omni::runner::fixjson(
848
+ &toomni(val),
849
+ &Flags {
850
+ null: nullflag,
851
+ name: None,
852
+ },
853
+ ))
854
+ }
855
+
856
+ pub fn inject_def_from_value(val: &Value) -> InjectDef {
857
+ let mut def = InjectDef::default();
858
+ if let Value::Map(_) = val {
859
+ let key = vget(val, "key");
860
+ if !key.is_noval() {
861
+ def.key = Some(key);
862
+ }
863
+ let meta = vget(val, "meta");
864
+ if !meta.is_noval() {
865
+ def.meta = Some(meta);
866
+ }
867
+ let base = vget(val, "base");
868
+ if let Value::Str(text) = base {
869
+ def.base = Some(text);
870
+ }
871
+ let dparent = vget(val, "dparent");
872
+ if !dparent.is_noval() {
873
+ def.dparent = Some(dparent);
874
+ }
875
+ let dpath = vget(val, "dpath");
876
+ if let Value::Str(text) = dpath {
877
+ def.dpath = Some(text.split('.').map(|part| part.to_string()).collect());
878
+ } else if let Value::List(list) = &dpath {
879
+ def.dpath = Some(
880
+ list.borrow()
881
+ .iter()
882
+ .map(|part| as_str_opt(part).unwrap_or_default())
883
+ .collect(),
884
+ );
885
+ }
886
+ }
887
+ def
888
+ }