1crate::ix!();
3
4error_tree!{
5 pub enum GrowerModelWriteSkillTreeError {
6 Default,
7 }
8}
9
10pub trait SkillTreeCrateWriter {
11
12 type Error;
13
14 fn skill_tree_write_crate_text(&self) -> Result<String,Self::Error>;
15}
16
17impl SkillTreeCrateWriter for GrowerModel {
18 type Error = GrowerModelWriteSkillTreeError;
19
20 fn skill_tree_write_crate_text(&self) -> Result<String, Self::Error> {
21 use std::collections::{HashMap, HashSet, VecDeque};
22
23 info!("model = {:#?}", self);
24
25 let all_nodes = self.core_string_skeleton().top_down_nodes();
30
31 let mut node_map = HashMap::<String, CoreSkeletalNode>::new();
32 let mut referenced_childs = HashSet::<String>::new();
33 let mut leaf_holder_names = HashSet::<String>::new();
34 let mut dispatch_names = HashSet::<String>::new();
35
36 for n in all_nodes {
37 match &n {
38 CoreSkeletalNode::Dispatch(d) => {
39 dispatch_names.insert(d.name().clone());
40 referenced_childs.extend(d.children().iter().map(|c| c.name().clone()));
41 }
42 CoreSkeletalNode::Aggregate(a) => {
43 referenced_childs.extend(a.children().iter().map(|c| c.name().clone()));
44 }
45 CoreSkeletalNode::LeafHolder(lh) => {
46 leaf_holder_names.insert(lh.name().clone());
47 }
48 }
49 node_map.insert(n.name().clone(), n);
50 }
51
52 let mut roots: Vec<String> = node_map
53 .keys()
54 .filter(|name| !referenced_childs.contains(*name))
55 .cloned()
56 .collect();
57 roots.sort(); trace!(?roots, "identified crate‑emission roots");
59
60 let mut crate_text = String::new();
64 crate_text.push_str(
65 r#"// SPDX-License-Identifier: GPL-3.0-only
66// This crate was generated by `capability` (GPLv3 licensed).
67// This generated crate is explicitly licensed under GPLv3.
68
69#![allow(unused_imports)]
70#![allow(unused_variables)]
71
72use std::fmt::Debug;
73use serde::{Serialize, Deserialize};
74use std::hash::Hash;
75use tracing::*;
76use variant_builder_macro::*;
77use rand_construct::*;
78use ai_descriptor::*;
79use derive_builder::*;
80use getset::*;
81
82"#,
83 );
84
85 let mut entrypoint_type = roots[0].to_string();
86
87 let root_is_dispatch = matches!(
88 node_map.get(&entrypoint_type),
89 Some(CoreSkeletalNode::Dispatch(_))
90 );
91
92 let top_name = if root_is_dispatch {
93 format!("{entrypoint_type}Top")
94 } else {
95 entrypoint_type.clone()
96 };
97
98 let top_snake = top_name.to_snake_case();
99 let top_kebab = top_name.to_kebab_case();
100
101 crate_text.push_str(&formatdoc!(r#"
102#[cfg(test)]
103mod {top_snake}_test_suite {{
104 use super::*;
105 use traced_test::*;
106 use tracing_setup::*;
107
108 #[traced_test]
109 fn random_instantiation_test() {{
110 type This = {top_name};
111 let item = This::random();
112 println!("------------------------[random-{top_kebab}]");
113 (0..120).for_each(|_| println!("{{}}\n", This::random().ai()));
114 //assert!(false); // uncomment this assertion to see the results
115 }}
116}}
117
118"#));
119
120 if root_is_dispatch {
121
122 info!("installing dispatch abstraction layer to the top");
123
124 let inner_field = entrypoint_type.to_snake_case(); let child = node_map.get(&entrypoint_type).expect("child must exist when building variants");
127
128 let header_text = match child {
129 CoreSkeletalNode::Dispatch(dchild) => dchild.descriptor(),
130 CoreSkeletalNode::Aggregate(a) => a.descriptor(),
131 CoreSkeletalNode::LeafHolder(lh) => lh.descriptor(),
132 };
133
134 crate_text.push_str(&formatdoc! {r#"
135 #[derive(VariantBuilder,Debug, Clone, ItemWithFeatures, RandConstruct, Hash, PartialEq, Eq)]
136 pub enum {top_name} {{
137 #[default]
138 #[ai(wrap = "ItemWithFeatures")]
139 #[nested_builder]
140 #[ai(header_prefix="{header_text} ")]
141 {entrypoint_type}({entrypoint_type}),
142 }}
143
144 "#});
145
146 crate_text = crate_text.replace(
148 &format!("type This = {entrypoint_type};"),
149 &format!("type This = {top_name};"),
150 );
151 }
152
153 info!("about to emit nodes");
154
155 fn leaf_descriptor_for(
159 leaf_holder_name: &str,
160 leaf_name: &str,
161 expansions: &AnnotatedLeafHolderExpansions,
162 ) -> String {
163 for holder in expansions.annotated_leaf_holders() {
164 if holder.leaf_holder_name() == leaf_holder_name {
165 for ann in holder.annotated_leaves() {
166 if ann.leaf_name() == leaf_name {
167 return ann.leaf_descriptor().to_string();
168 }
169 }
170 }
171 }
172 format!("No descriptor found for leaf '{leaf_name}'.")
173 }
174
175 let mut emitted = HashSet::<String>::new();
179
180 #[instrument(level = "trace", skip_all)]
181 fn emit_node(
182 name: &str,
183 node_map: &HashMap<String, CoreSkeletalNode>,
184 leaf_holder_names: &HashSet<String>,
185 dispatch_names: &HashSet<String>,
186 emitted: &mut HashSet<String>,
187 crate_text: &mut String,
188 model: &GrowerModel,
189 ) {
190 if !emitted.insert(name.to_string()) {
191 trace!(node = name, "already emitted — skipping");
192 return;
193 }
194
195 let node = match node_map.get(name) {
196 Some(n) => n,
197 None => {
198 warn!(node = name, "child referenced but not found in map");
199 return;
200 }
201 };
202
203 debug!("emit_node, passed preliminary checks");
204
205 match node {
206 CoreSkeletalNode::Dispatch(d) => {
208 let mut variants = String::new();
209
210 for (idx, ch) in d.children().iter().enumerate() {
211
212 let child = node_map.get(ch.name())
213 .expect("child must exist when building variants");
214
215 if idx == 0 {
216 variants.push_str("#[default]\n");
217 }
218
219 match child {
220 CoreSkeletalNode::Dispatch(dchild) => {
222 variants.push_str(" #[ai(wrap = \"ItemWithFeatures\")]\n");
223 variants.push_str(" #[nested_builder]\n");
224 variants.push_str(&format!(
225 " #[ai(header_prefix = \"{} \")]\n",
226 dchild.descriptor()
227 ));
228 }
229 CoreSkeletalNode::Aggregate(_) => {
231 variants.push_str(" #[ai(wrap = \"ItemWithFeatures\")]\n");
232 }
233 CoreSkeletalNode::LeafHolder(lh) => {
235 variants.push_str(" #[no_builder]\n");
236 variants.push_str(&format!(
237 " #[ai(\"{}\")]\n",
238 lh.descriptor()
239 ));
240 }
241 }
242
243 variants.push_str(&format!(" {}({}),\n", ch.name(), ch.name()));
245 }
246
247 crate_text.push_str(&formatdoc!(
248 r#"
249 #[derive(VariantBuilder, Debug, Clone, ItemWithFeatures, RandConstruct, Hash, PartialEq, Eq)]
250 pub enum {ename} {{
251 {variants}
252 }}
253
254 "#,
255 ename = d.name(),
256 variants = variants.trim_end(),
257 ));
258 }
259
260 CoreSkeletalNode::Aggregate(a) => {
262 let mut fields = String::new();
263 let mut found_opt_child = false;
264
265 for ch in a.children() {
266
267 let field_name = ch.name().to_case(Case::Snake);
268
269 let child = node_map.get(ch.name())
270 .expect("child must exist when building variants");
271
272 let child_descriptor = match child {
273 CoreSkeletalNode::Dispatch(dchild) => dchild.descriptor(),
274 CoreSkeletalNode::Aggregate(a) => a.descriptor(),
275 CoreSkeletalNode::LeafHolder(lh) => lh.descriptor(),
276 };
277
278 if *ch.optional() {
279 let p = *ch.probability() as f64 / 100.0;
280
281 let opt_header = match found_opt_child {
282 true => "No ",
283 false => "Specifically contains no ",
284 };
285
286 fields.push_str(&format!(
287 r#"
288 #[ai(feature_if_none="{opt_header}'{child}' module.")]
289 #[ai(feature_prefix_if_some="{child_descriptor} ")]
290 #[rand_construct(psome={prob})]
291 {field}: Option<{child}>,"#,
292 child = ch.name(),
293 prob = p,
294 field = field_name,
295 ));
296
297 found_opt_child = true;
298
299 } else {
300 fields.push_str(&format!(
301 r#"
302 #[ai("{child_descriptor}")]
303 {field}: {child},"#,
304 child = ch.name(),
305 field = field_name,
306 ));
307
308 }
309 }
310
311 crate_text.push_str(&formatdoc!(
312 r#"
313 #[derive(Builder, Debug, Clone, ItemWithFeatures, RandConstruct, Default, Hash, PartialEq, Eq, Getters)]
314 #[builder(pattern="owned", setter(into))]
315 #[ai("{desc}")]
316 pub struct {sname} {{
317 {fields}
318 }}
319
320 "#,
321 desc = a.descriptor(),
322 sname = a.name(),
323 fields = fields.trim_end(),
324 ));
325 }
326
327 CoreSkeletalNode::LeafHolder(lh) => {
329 let mut variants = String::new();
330 for (idx, leaf) in lh.leaves().iter().enumerate() {
331 if idx == 0 {
332 variants.push_str("#[default]\n");
333 }
334 let ld = leaf_descriptor_for(
335 lh.name(),
336 leaf,
337 model.annotated_leaf_holder_expansions(),
338 );
339 variants.push_str(&format!(
340 " #[ai(\"{ld}\")]\n {leaf},\n",
341 ld = ld,
342 leaf = leaf
343 ));
344 }
345
346 crate_text.push_str(&formatdoc!(
347 r#"
348 #[derive(Debug, Clone, ItemFeature, RandConstruct, Default, Hash, PartialEq, Eq)]
349 pub enum {ename} {{
350 {variants}
351 }}
352
353 "#,
354 ename = lh.name(),
355 variants = variants.trim_end(),
356 ));
357 }
358 }
359 }
360
361 let mut queue: VecDeque<String> = roots.into_iter().collect();
363 while let Some(current) = queue.pop_front() {
364
365 debug!("processing {:#?}", current);
366
367 emit_node(
368 ¤t,
369 &node_map,
370 &leaf_holder_names,
371 &dispatch_names,
372 &mut emitted,
373 &mut crate_text,
374 self,
375 );
376
377 debug!("emit_node terminated");
378
379 if let Some(node) = node_map.get(¤t) {
380 match node {
381 CoreSkeletalNode::Dispatch(d) => {
382 debug!("processing Dispatch node {:#?}", d);
383 for ch in d.children() {
384 if !emitted.contains(ch.name()) {
385 queue.push_back(ch.name().clone());
386 }
387 }
388 }
389 CoreSkeletalNode::Aggregate(a) => {
390 debug!("processing Aggregate node {:#?}", a);
391 for ch in a.children() {
392 if !emitted.contains(ch.name()) {
393 queue.push_back(ch.name().clone());
394 }
395 }
396 }
397 CoreSkeletalNode::LeafHolder(lh) => {
398 debug!("processing LeafHolder node {:#?}", lh);
399 }
400 }
401 }
402 }
403
404 Ok(crate_text)
405 }
406}
407
408#[cfg(test)]
409mod grower_model_tests {
410 use super::*;
411
412 #[traced_test]
413 async fn basic_smoke() -> Result<(),GrowerModelWriteSkillTreeError> {
414
415 let mut map = HashMap::<&'static str, &[&'static str]>::default();
416
417 map.insert("foxes", &[
418 "fox-advanced-social-group-coordination-and-complex-cooperative-task-execution",
419 "fox-performance-conditioning-for-speed-and-endurance",
420 "fox-advanced-performance-design-and-precision-task-choreography-mastery",
421 "fox-initial-directional-cue-response-training-to-basic-verbal-and-hand-gestures",
422 "fox-basic-den-and-resting-area-familiarization-and-conditioning",
423 "fox-basic-target-following-over-short-distances-and-simple-pathways",
424 "fox-social-group-coordination-and-cooperative-task-conditioning",
425 "fox-simple-habitat-maintenance-and-comfort-management-awareness",
426 "fox-long-duration-station-holding-and-task-performance-under-significant-distractions",
427 "fox-positive-food-reward-conditioning-with-precise-delivery-timing",
428 "fox-performance-prop-interaction-techniques",
429 "fox-soft-vocal-tone-and-human-voice-conditioning-for-trust-building",
430 "fox-positive-reinforcement-training-techniques",
431 "fox-object-manipulation-under-forest-conditions",
432 "fox-advanced-object-manipulation-in-forest-settings",
433 "fox-basic-station-area-familiarization-and-short-duration-conditioning",
434 "fox-target-tracking-through-variable-terrain",
435 "fox-positive-food-association-conditioning-with-human-interaction",
436 "fox-basic-agility-and-precision-foot-placement-training-over-low-obstacles",
437 "fox-social-performance-cue-responsiveness",
438 "fox-station-duration-extension-up-to-3-minutes-under-controlled-distractions",
439 "fox-stress-reduction-and-socialization-methods",
440 "fox-highly-precise-target-following-and-navigation-through-challenging-and-variable-environments",
441 "fox-controlled-introduction-to-minimal-environmental-distractions-and-stimuli",
442 "fox-complex-directional-cue-response-with-combined-visual-verbal-and-tactile-signals",
443 "fox-target-identification-and-tracking-skills",
444 "fox-advanced-territorial-navigation-resource-management-and-boundary-recognition-training",
445 "fox-intermediate-agility-course-navigation-with-complex-terrain-and-obstacles",
446 "fox-agility-and-performance-cue-mastery",
447 "fox-advanced-object-manipulation-tool-use-and-complex-task-performance-conditioning",
448 "fox-station-duration-training-starting-from-15-to-45-seconds",
449 "fox-simple-social-presence-conditioning-with-multiple-handlers-and-conspecifics",
450 "fox-extended-target-following-and-navigation-over-complex-and-variable-terrain",
451 "fox-gradual-human-presence-desensitization-through-controlled-proximity-management",
452 "fox-adaptive-responsiveness-to-sophisticated-multi-modal-command-sequences",
453 "fox-initial-observation-of-stress-and-relaxation-body-language-signals",
454 "fox-simple-object-touch-retrieval-and-target-response-conditioning",
455 "fox-controlled-conditioning-to-low-intensity-environmental-distractions",
456 "fox-precision-object-manipulation-placement-and-sequential-task-training",
457 "fox-comprehensive-emotional-and-stress-state-monitoring-for-optimal-engagement",
458 "fox-agility-course-vertical-scaling",
459 "fox-basic-grooming-health-inspection-and-handling-desensitization",
460 "fox-responsiveness-conditioning-to-subtle-human-body-language-and-gesture-cues",
461 "fox-positive-reward-frequency-and-type-optimization-for-task-complexity",
462 "fox-initial-scent-familiarization-and-positive-object-association",
463 "fox-comprehensive-problem-solving-adaptive-behavior-and-task-sequencing-conditioning",
464 "fox-extended-grooming-handling-and-comprehensive-health-examination-conditioning",
465 "fox-group-social-coordination-techniques",
466 "fox-advanced-agility-course-precision-training",
467 "fox-extended-performance-of-complex-sequential-behavioral-tasks-with-memory-retention",
468 "fox-controlled-introduction-to-basic-hand-proximity-and-gentle-touch",
469 "fox-basic-eye-contact-duration-awareness-and-conditioning",
470 "fox-group-social-cue-training",
471 "fox-agility-course-navigation-with-complex-obstacles",
472 "fox-advanced-object-discrimination-training",
473 "fox-targeted-enrichment-exercise-regimens",
474 "fox-controlled-conditioning-to-moderate-environmental-and-social-distractions",
475 "fox-social-hierarchy-performance-management",
476 ]);
477
478 map.insert("real-estate", &[
479 "real-estate-72-hour-clause-contingent-sale-risk-management",
480 "real-estate-abstract-of-title-verification-and-analysis",
481 "real-estate-acceleration-clause-default-risk-management",
482 "real-estate-accession-property-rights-clarification",
483 "real-estate-acreage-measurement-and-land-valuation",
484 "real-estate-ad-valorem-property-tax-management",
485 "real-estate-adjustable-rate-mortgage-risk-mitigation",
486 "real-estate-adjusted-basis-capital-gain-calculation",
487 "real-estate-adverse-possession-property-rights-defense",
488 "real-estate-affordable-housing-investment-and-social-impact-strategy",
489 "real-estate-agency-transaction-representation-management",
490 "real-estate-agent-transaction-facilitation-management",
491 "real-estate-air-rights-acquisition-and-utilization",
492 "real-estate-alluvion-and-accretion-property-boundary-management",
493 "real-estate-american-land-title-association-compliance",
494 "real-estate-amortizing-loan-management-and-strategy",
495 "real-estate-anchor-store-commercial-investment-strategy",
496 "real-estate-annexation-and-zoning-impact-management",
497 "real-estate-annual-percentage-rate-cost-assessment",
498 "real-estate-anti-money-laundering-compliance-and-risk-management",
499 "real-estate-apartment-investment-analysis-and-management",
500 "real-estate-appraisal-property-valuation-strategy",
501 "real-estate-appraisal-standards-professional-compliance",
502 "real-estate-appraised-value-assessment-and-validation",
503 "real-estate-appurtenant-easement-rights-and-valuation",
504 "real-estate-arms-length-transaction-principle-compliance",
505 "real-estate-arrears-debt-collection-and-management",
506 "real-estate-asking-price-negotiation-strategy",
507 "real-estate-asset-identification-and-financial-resource-management",
508 "real-estate-assignment-law-contractual-rights-transfer",
509 "real-estate-assumption-of-mortgage-transaction-management",
510 "real-estate-attorney-at-law-transaction-and-legal-protection",
511 "real-estate-attorney-in-fact-financial-authority-management",
512 "real-estate-avulsion-property-boundary-risk-management",
513 "real-estate-balance-sheet-preparation-and-financial-reporting",
514 "real-estate-balloon-mortgage-structure-and-risk-management",
515 "real-estate-bargain-and-sale-deed-risk-clarification",
516 "real-estate-benchmarking-investment-performance-management",
517 "real-estate-beneficiary-rights-and-management",
518 "real-estate-bequest-property-transfer-and-legacy-planning",
519 "real-estate-bilateral-contract-management-and-enforcement",
520 "real-estate-bill-of-sale-documentation-and-transfer-management",
521 "real-estate-blanket-loan-portfolio-financing-strategy",
522 "real-estate-blockchain-title-transfer-and-risk-management",
523 "real-estate-boiler-insurance-coverage-and-risk-management",
524 "real-estate-bona-fide-purchaser-rights-and-protection",
525 "real-estate-book-value-calculation-and-valuation-management",
526 "real-estate-boot-property-exchange-and-tax-management",
527 "real-estate-boundary-determination-and-dispute-resolution",
528 "real-estate-bpo-standards-and-guidelines-compliance",
529 "real-estate-broker-transaction-integrity-management",
530 "real-estate-brokerage-market-access-management",
531 "real-estate-brokers-price-opinion-valuation-and-compliance",
532 "real-estate-bubble-market-risk-awareness",
533 ]);
534
535 map.insert("zoosemiosis", &[
536 "zoosemiotic-danger-safety-alarm-calls-and-predator-response-training",
537 "zoosemiotic-danger-safety-context-driven-symbolic-learning-and-adaptation",
538 "zoosemiotic-danger-safety-cross-species-threat-recognition-and-signaling",
539 "zoosemiotic-danger-safety-minimal-ambiguity-and-rapid-sign-processing-training",
540 "zoosemiotic-danger-safety-risk-assessment-and-group-vigilance-pattern-recognition",
541 "zoosemiotic-family-social-bonds-cooperation-conflict-and-reconciliation-pattern-training",
542 "zoosemiotic-family-social-bonds-minimal-symbolic-density-in-social-maintenance-signals",
543 "zoosemiotic-family-social-bonds-parent-offspring-signaling-patterns",
544 "zoosemiotic-family-social-bonds-social-affiliation-and-hierarchy-sign-recognition",
545 "zoosemiotic-food-nourishment-cross-species-competition-and-cooperation-signals",
546 "zoosemiotic-food-nourishment-foraging-and-feeding-sign-pattern-recognition",
547 "zoosemiotic-food-nourishment-group-coordination-in-hunting-and-gathering",
548 "zoosemiotic-food-nourishment-resource-availability-and-minimal-sign-density-calibration",
549 "zoosemiotic-food-nourishment-symbolic-social-learning-and-cultural-transmission",
550 "zoosemiotic-life-death-affiliative-behavior-during-distress-events",
551 "zoosemiotic-life-death-alarm-signal-pattern-analysis",
552 "zoosemiotic-life-death-alarm-signal-pattern-analysis2",
553 "zoosemiotic-life-death-minimal-energy-signaling-and-survival-patterns",
554 "zoosemiotic-life-death-ritualized-behavior-and-social-learning-calibration",
555 "zoosemiotic-life-death-symbolic-recognition-in-animal-behavior",
556 "zoosemiotic-motion-rest-cross-species-symbolic-motion-pattern-calibration",
557 "zoosemiotic-motion-rest-group-movement-coordination-and-minimal-energy-signals",
558 "zoosemiotic-motion-rest-locomotion-patterns-and-symbolic-social-signals",
559 "zoosemiotic-motion-rest-predator-and-prey-chase-pattern-symbol-recognition",
560 "zoosemiotic-motion-rest-resting-state-and-social-relaxation-sign-recognition",
561 "zoosemiotic-sun-moon-circadian-rhythm-and-signal-pattern-calibration",
562 "zoosemiotic-sun-moon-cross-species-temporal-signaling-optimization",
563 "zoosemiotic-sun-moon-minimal-density-energy-expenditure-calibration",
564 "zoosemiotic-sun-moon-nocturnal-and-diurnal-behavior-pattern-recognition",
565 "zoosemiotic-sun-moon-seasonal-migration-and-navigation-signal-analysis",
566 "zoosemiotic-time-space-cross-species-territorial-dispute-resolution-signals",
567 "zoosemiotic-time-space-home-range-recognition-and-spatial-symbolic-cognition",
568 "zoosemiotic-time-space-minimal-density-symbolic-navigation-training",
569 "zoosemiotic-time-space-navigation-patterns-and-migratory-route-symbols",
570 "zoosemiotic-time-space-territorial-signaling-and-boundary-recognition",
571 ]);
572
573 map.insert("owl", &[
574 "owl-adaptive-responsiveness-to-highly-sophisticated-multi-modal-command-sequences",
575 "owl-advanced-flight-pattern-choreography",
576 "owl-advanced-object-manipulation-and-complex-task-performance-conditioning",
577 "owl-advanced-performance-design-and-precision-flight-choreography-mastery",
578 "owl-advanced-problem-solving-adaptive-behavior-and-flight-sequencing-conditioning",
579 "owl-basic-eye-contact-duration-awareness-and-conditioning",
580 "owl-basic-flight-agility-and-navigation-conditioning-over-low-level-obstacles",
581 "owl-basic-health-inspection-handling-and-equipment-desensitization",
582 "owl-basic-observation-of-stress-and-relaxation-body-language-signals",
583 "owl-basic-station-area-familiarization-and-short-duration-conditioning",
584 "owl-basic-target-following-over-short-distances-and-simple-flight-paths",
585 ]);
586
587 map.insert("adaptive-technology", &[
588 "active-camouflage-metamaterial-optical-field-adaptation-training",
589 "adaptive-biomechanical-control-algorithm-human-integration-calibration",
590 "adaptive-camouflage-field-integrated-microelectronics-optimization",
591 "adaptive-composite-armor-dynamic-stiffness-response-calibration",
592 "adaptive-drone-network-minimal-communication-latency-calibration",
593 "adaptive-exoskeleton-predictive-biomechanical-interface-training",
594 "adaptive-medical-response-minimal-human-intervention-calibration",
595 "adaptive-reaction-control-micro-scale-thruster-precision",
596 "adaptive-thermal-management-for-high-energy-portable-devices",
597 "additive-manufacturing-complex-metamaterial-precision-training",
598 "advanced-augmented-reality-hud-and-sensor-fusion-training",
599 "advanced-cryostasis-vitrification-and-cellular-integrity-preservation",
600 "advanced-field-medical-kit-ai-driven-autonomous-diagnosis",
601 "advanced-gravitational-field-manipulation-and-frame-dragging-control",
602 "advanced-materials-flexible-armor-and-metamaterial-engineering",
603 "advanced-medical-biofoam-hemostatic-and-tissue-regeneration",
604 "advanced-microfusion-direct-electrical-energy-conversion",
605 "ai-driven-nanomachine-coordination-and-autonomous-repair-training",
606 "antigravity-device-minimal-gravitational-distortion-calibration",
607 "autonomous-adaptive-combat-vehicle-sensor-degradation-tolerance",
608 "autonomous-nanoscale-molecular-manufacturing-training",
609 "autonomous-robotic-assembly-complex-structures-optimization",
610 "autonomous-vehicle-combat-decision-making-and-tactical-autonomy",
611 "biocompatible-neural-implant-long-term-stability-calibration",
612 "biomechanical-predictive-algorithms-for-armor-mobility-optimization",
613 "compact-directed-energy-weapon-miniaturization-and-efficiency-training",
614 "compact-fusion-reactor-energy-density-and-confinement-optimization",
615 "compact-life-support-environmental-control-system-calibration",
616 "compact-particle-accelerator-miniaturization-and-field-control",
617 "composite-material-integrity-under-extreme-condition-calibration",
618 "cryopreservation-vitrification-cellular-integrity-optimization",
619 "distributed-autonomous-vehicle-communication-robustness-calibration",
620 "drone-swarm-tactical-coordination-and-autonomous-control",
621 "dynamic-structural-health-monitoring-system-feedback-calibration",
622 "exoskeleton-neural-integration-with-minimal-latency-optimization",
623 "functional-metamaterial-cloaking-infrared-and-radar-invisibility-calibration",
624 "hard-light-field-generation-with-electromagnetic-force-feedback",
625 "high-density-information-storage-and-quantum-state-encoding",
626 "high-density-neuromorphic-computing-architecture-calibration",
627 "high-density-ultracapacitor-energy-release-and-storage-optimization",
628 "high-efficiency-electromagnetic-propulsion-and-energy-transfer",
629 "high-efficiency-plasma-generation-portable-device-optimization",
630 "high-energy-rifle-containment-field-density-calibration",
631 "high-frequency-directed-energy-field-density-calibration",
632 "high-temperature-superconducting-magnet-field-density-calibration",
633 "high-temperature-superconductor-miniaturization-and-field-density-calibration",
634 "hybrid-electric-propellant-thruster-miniaturization-and-efficiency-calibration",
635 "hybrid-quantum-classical-computational-architecture-integration",
636 "individual-precision-controlled-aerobraking-and-landing-algorithms",
637 "individual-scale-precision-heat-shielding-for-reentry-training",
638 "infantry-scale-electromagnetic-cloaking-field-optimization",
639 "instantaneous-neural-encoding-and-decoding-algorithms",
640 "integrated-eye-tracking-and-real-time-object-recognition",
641 "integrated-holographic-display-resolution-and-accuracy-calibration",
642 "low-latency-neural-feedback-for-combat-enhancement-training",
643 "low-power-edge-computing-sensor-fusion-density-optimization",
644 "micro-fusion-reactor-prototype-net-positive-energy-output-calibration",
645 "micro-scale-thermal-management-for-high-density-devices",
646 "microfluidic-on-demand-drug-synthesis-and-delivery-precision",
647 "microfluidic-on-demand-pharmaceutical-synthesis-precision-calibration",
648 "miniature-thruster-reaction-control-and-aerodynamic-calibration",
649 ]);
650
651 map.insert("electronic-music", &[
652 "adaptive-ambient-space-design",
653 "adaptive-attack-release-envelope",
654 "adaptive-attack-release-tail-modeling",
655 "adaptive-binaural-beat-generation",
656 "adaptive-binaural-room-modeling",
657 "adaptive-biofeedback-frequency-design",
658 "adaptive-bowed-string-harmonics",
659 "adaptive-brainwave-phase-locking",
660 "adaptive-build-break-energy-control",
661 "adaptive-chop-density-control",
662 "adaptive-crossfade-loop-blending",
663 ]);
664
665 map.insert("river-town", &[
666 "alleyway-agility",
667 "amphibious-combat-tactics",
668 "animal-flow",
669 "aquatic-grappling",
670 "balance",
671 "bar-fighting",
672 "boxing",
673 "breakdancing",
674 "breathwork",
675 "bushcraft",
676 "calisthenics",
677 "camouflage",
678 "canoeing",
679 "capoeira",
680 "close-quarters-combat",
681 "cobblestone-street-running",
682 "cold-water-conditioning",
683 "docs",
684 "evasion",
685 "fire-environment-qigong",
686 "fishing",
687 "forest-based-archery",
688 "forest-orienteering",
689 "forest-slacklining",
690 "guerrilla-combat-tactics",
691 "gymnastics",
692 "historic-meditation",
693 "historic-urban-bushcraft",
694 "historical-archery",
695 "historical-european-martial-arts",
696 "historical-site-yoga",
697 "hydrotherapy",
698 "ice-fishing",
699 "improvised-combat",
700 "jedi-mind-tricks",
701 "judo",
702 "knife-fighting",
703 "knife-throwing",
704 "krav-maga",
705 "lockpicking",
706 "love",
707 "medieval-calisthenics",
708 "meditation",
709 "mouvement-naturel",
710 "natural-movement",
711 "parkour",
712 "patch-bay",
713 "pilates",
714 "primitive-fish-trapping",
715 "primitive-hunting",
716 "qigong",
717 "quigong",
718 "rafting",
719 "river-crossing-techniques",
720 "river-running",
721 "river-swimming",
722 "riverbank-bushcraft",
723 "riverside-balance-training",
724 "riverside-yoga",
725 "rooftop-traversal",
726 "sanskrit-yoga",
727 "snow-love",
728 "snow-love-building",
729 "snow-love-building-advanced",
730 "snow-love-building-masterful",
731 "snow-love-campfire",
732 "spearfishing",
733 "stealth-movement",
734 "swiftwater-parkour",
735 "swiftwater-rescue",
736 "tai-chi",
737 "target",
738 "trail-running",
739 "trapping",
740 "tree-climbing",
741 "urban-entry-techniques",
742 "urban-foraging",
743 "urban-historical-parkour",
744 "urban-slacklining",
745 "urban-stealth",
746 "waterborne-archery",
747 "watercraft-construction",
748 "whitewater-kayaking",
749 "wilderness-first-aid",
750 "woodland-yoga",
751 "yoga-sanskrit",
752 ]);
753
754 let generated_skill_tree_workspaces_dir = "generated-skill-tree-workspaces";
755
756 let do_these = [
757 "river-town",
760 ];
761
762 for (workspace_key, workspace_set) in map.iter() {
763
764 if !do_these.is_empty() && !do_these.contains(workspace_key) {
765 continue;
766 }
767
768 let mut set_members = vec![];
769
770 for name in workspace_set.iter() {
771 if let Ok(model)
772 = GrowerModel::load_from_file(format!("../patch-bay/{name}.json"))
773 .await
774 {
775 let crate_text = model.skill_tree_write_crate_text()?;
776
777 let cargo_toml_text = formatdoc!{
778 r#"
779 [package]
780 name = "{name}"
781 license = "GPL-3.0-only"
782 license-text = "LICENSE"
783 authors = ["klebs6 <tpk3.mx@gmail.com>"]
784 version = "0.1.0"
785 edition = "2024"
786 description = "Skill tree crate for the {name} system."
787 keywords = ["grower", "skill", "tree", "simulation", "generator"]
788 categories = ["simulation"]
789
790 [dependencies]
791 ai-descriptor.workspace = true
792 ai-descriptor-derive.workspace = true
793 export-magic.workspace = true
794 once_cell.workspace = true
795 rand.workspace = true
796 derive_builder.workspace = true
797 getset.workspace = true
798 tracing.workspace = true
799 tracing-setup.workspace = true
800 traced-test.workspace = true
801 serde.workspace = true
802 variant-builder-macro.workspace = true
803 rand-construct.workspace = true
804 "#};
805
806 let license_text = formatdoc!{
807 r#"Licensed under GPLv3. Downstream generation byproducts inherit GPLv3."#
808 };
809
810 std::fs::create_dir_all(format!("../{generated_skill_tree_workspaces_dir}/{workspace_key}/{name}/src")).expect("expected create dir success");
811
812 std::fs::write(format!("../{generated_skill_tree_workspaces_dir}/{workspace_key}/{name}/src/lib.rs"), crate_text).expect("we expected to be able to write this file");
813 std::fs::write(format!("../{generated_skill_tree_workspaces_dir}/{workspace_key}/{name}/Cargo.toml"), cargo_toml_text).expect("we expected to be able to write the Cargo.toml");
814 std::fs::write(format!("../{generated_skill_tree_workspaces_dir}/{workspace_key}/{name}/LICENSE"), license_text).expect("we expected to be able to write the SPPL license file");
815
816 set_members.push(name);
817
818 } else {
819 warn!("expected to unpack this file ../patch-bay/{name}.json");
820 }
821 }
822
823 let workspace_cargo_toml_text = formatdoc! {
824 r#"
825 [workspace]
826 members = [
827 {members}
828 ]
829
830 [workspace.dependencies]
831 ai-descriptor = {{ version = "0.11.0", path = "/Users/kleb/bethesda/work/repo/klebs-general/ai-descriptor" }}
832 ai-descriptor-derive = {{ version = "0.6.0", path = "/Users/kleb/bethesda/work/repo/klebs-general/ai-descriptor-derive" }}
833 derive_builder = "0.20.2"
834 export-magic = "0.3.6"
835 getset = "0.1.4"
836 once_cell = "1.20.2"
837 rand = "0.8.5"
838 rand-construct = {{ version = "0.14.0", path = "/Users/kleb/bethesda/work/repo/klebs-general/rand-construct" }}
839 serde = "1.0.219"
840 traced-test = {{ version = "1.0.3", path = "/Users/kleb/bethesda/work/repo/klebs-general/traced-test" }}
841 tracing = "0.1.41"
842 tracing-setup = {{ version = "1.0.3", path = "/Users/kleb/bethesda/work/repo/klebs-general/tracing-setup" }}
843 variant-builder-macro = {{ version = "0.3.0", path = "/Users/kleb/bethesda/work/repo/klebs-general/variant-builder-macro" }}
844 "#,
845 members = set_members
846 .iter()
847 .map(|name| format!(" \"{name}\""))
848 .collect::<Vec<_>>()
849 .join(",\n")
850 };
851
852 let workspace_makefile_text = formatdoc! {
853 r#"
854 .PHONY: build active test run test_all
855 ENTRYPOINT := {workspace_key}
856
857 #RUSTFLAGS := "-Awarnings -Z time-passes"
858 RUSTFLAGS := -Awarnings RUST_BACKTRACE=1
859 #CARGO := env CARGO_MSG_LIMIT=15 CARGO_BUILD_JOBS=12 NUM_JOBS=12 cargo
860 CARGO := MAKEFLAGS= env CARGO_BUILD_JOBS=12 NUM_JOBS=12 cargo
861 BUILD := build --verbose
862 RUN := run
863 TEST := test
864
865 ACTIVE_PACKAGE := {first_package_name}
866
867 DEFAULT := test_all
868 #DEFAULT := test
869 #DEFAULT := build
870
871 #FEATURES := --features "enable_stress_test"
872 FEATURES := --features ""
873
874 default: $(DEFAULT)
875
876 #NOCAPTURE := --nocapture
877 #NOCAPTURE :=
878
879 #----------------------------------------------[here are our rules]
880
881 run:
882 RUSTFLAGS=$(RUSTFLAGS) $(CARGO) run -p $(ACTIVE_PACKAGE) --bin $(ENTRYPOINT) $(FEATURES)
883
884 build:
885 RUSTFLAGS=$(RUSTFLAGS) $(CARGO) $(BUILD) $(FEATURES)
886
887 active:
888 RUSTFLAGS=$(RUSTFLAGS) $(CARGO) $(BUILD) -p $(ACTIVE_PACKAGE) $(FEATURES)
889
890 test:
891 RUST_MIN_STACK=8388608 RUST_LOG=trace RUSTFLAGS=$(RUSTFLAGS) $(CARGO) $(TEST) -p $(ACTIVE_PACKAGE) -- $(NOCAPTURE)
892
893 test_all:
894 RUSTFLAGS=$(RUSTFLAGS) $(CARGO) $(TEST) --workspace -- $(NOCAPTURE)
895 "#,
896 first_package_name = set_members[0],
897 workspace_key = workspace_key
898 }.replace("\n ", "\n\t"); std::fs::write(format!("../{generated_skill_tree_workspaces_dir}/{workspace_key}/Cargo.toml"), workspace_cargo_toml_text).expect("we expected to be able to write the workspace Cargo.toml");
901 std::fs::write(format!("../{generated_skill_tree_workspaces_dir}/{workspace_key}/Makefile"), workspace_makefile_text).expect("we expected to be able to write the workspace Makefile");
902 }
903
904 Ok(())
905 }
906}
907
908