capability_example/
manual_flow_try_to_fix_missing_field.rs

1// ---------------- [ File: capability-example/src/manual_flow_try_to_fix_missing_field.rs ]
2crate::ix!();
3
4/// Called when validation of the partial model fails with a known "missing partial" error.
5/// We query the `FlowStrategy` to see if it can fill in the missing piece automatically or by prompting the user.
6#[instrument(level = "trace", skip_all)]
7pub async fn manual_flow_try_to_fix_missing_field<S: GrowerFlowStrategy>(
8    strategy:      &S,
9    partial_model: &mut PartiallyGrownModel,
10    grower_inputs: &GrowerInputs,
11    error:         &GrowerModelGenerationInvalidPartial,
12    cli:           &ManualGrowerFlowCliArgs,
13
14) -> Result<(), ManualGrowerFlowError> {
15
16    match error {
17
18        GrowerModelGenerationInvalidPartial::MissingJustifiedGrowerTreeConfiguration => {
19            // We call the strategy's "fill_justified_tree_configuration" method
20            if let Some(config) = strategy
21                .fill_justified_tree_configuration(partial_model, grower_inputs)
22                .await?
23            {
24                partial_model.set_maybe_ungrown_justified_grower_tree_configuration(Some(config));
25                let path = cli.calculate_partial_path(grower_inputs);
26                partial_model.save_to_file(&path).await?;
27            } else {
28                // The strategy returned None => we do not fill it => bail out
29                return Err(ManualGrowerFlowError::FillJustifiedTreeConfigurationError);
30            }
31        }
32
33        GrowerModelGenerationInvalidPartial::MissingJustifiedStringSkeleton => {
34            let tree_conf = partial_model
35                .maybe_ungrown_justified_grower_tree_configuration()
36                .as_ref()
37                .expect("validate() wouldn't let us get here if that was also missing");
38            if let Some(skel) = strategy
39                .fill_justified_string_skeleton(partial_model, grower_inputs, tree_conf)
40                .await?
41            {
42                partial_model.set_maybe_ungrown_justified_string_skeleton(Some(skel));
43                let path = cli.calculate_partial_path(grower_inputs);
44                partial_model.save_to_file(&path).await?;
45            } else {
46                return Err(ManualGrowerFlowError::FillJustifiedStringSkeletonError);
47            }
48        }
49
50        GrowerModelGenerationInvalidPartial::MissingStrippedStringSkeleton => {
51            // We can actually fill this automatically ourselves (like in the old code),
52            // but let's illustrate how we might delegate to the strategy for consistency:
53            let justified_skel = partial_model
54                .maybe_ungrown_justified_string_skeleton()
55                .as_ref()
56                .expect("We wouldn't get here if that was missing");
57            let stripped = StrippedStringSkeleton::from(justified_skel.clone());
58            partial_model.set_maybe_ungrown_stripped_string_skeleton(Some(stripped));
59
60            let path = cli.calculate_partial_path(grower_inputs);
61            partial_model.save_to_file(&path).await?;
62            // No strategy call needed if we do it ourselves, or we could do it in strategy
63        }
64
65        GrowerModelGenerationInvalidPartial::MissingCoreStringSkeleton => {
66            let tree_conf = partial_model
67                .maybe_ungrown_justified_grower_tree_configuration()
68                .as_ref()
69                .expect("We wouldn't get here if that was missing");
70            let stripped_skel = partial_model
71                .maybe_ungrown_stripped_string_skeleton()
72                .as_ref()
73                .expect("We wouldn't get here if that was missing");
74            if let Some(core) = strategy
75                .fill_core_string_skeleton(partial_model, grower_inputs, tree_conf, stripped_skel)
76                .await?
77            {
78                partial_model.set_maybe_ungrown_core_string_skeleton(Some(core));
79                let path = cli.calculate_partial_path(grower_inputs);
80                partial_model.save_to_file(&path).await?;
81            } else {
82                return Err(ManualGrowerFlowError::FillMissingCoreStringSkeletonError);
83            }
84        }
85
86        GrowerModelGenerationInvalidPartial::MissingAnnotatedLeafHolderExpansions => {
87            let tree_conf = partial_model
88                .maybe_ungrown_justified_grower_tree_configuration()
89                .as_ref()
90                .expect("We wouldn't get here if that was missing");
91            let core_skel = partial_model
92                .maybe_ungrown_core_string_skeleton()
93                .as_ref()
94                .expect("We wouldn't get here if that was missing");
95            if let Some(ann) = strategy
96                .fill_annotated_leaf_holder_expansions(
97                    partial_model,
98                    grower_inputs,
99                    tree_conf,
100                    core_skel,
101                )
102                .await?
103            {
104                partial_model.set_maybe_ungrown_annotated_leaf_holder_expansions(Some(ann));
105                let path = cli.calculate_partial_path(grower_inputs);
106                partial_model.save_to_file(&path).await?;
107            } else {
108                return Err(ManualGrowerFlowError::FillMissingAnnotatedLeafHolderError);
109            }
110        }
111    }
112
113    Ok(())
114}