chore: fix nickel-roundtrip render and optimize/cleanup
This commit is contained in:
parent
e58905c1f1
commit
b906168f6d
@ -325,7 +325,10 @@ impl RoundtripConfig {
|
||||
})?;
|
||||
|
||||
// Parse TOML form definition
|
||||
let form = form_parser::parse_toml(&form_content)?;
|
||||
let mut form = form_parser::parse_toml(&form_content)?;
|
||||
|
||||
// Migrate to unified elements format if needed
|
||||
form.migrate_to_elements();
|
||||
|
||||
// Extract base directory for resolving relative paths (includes, fragments)
|
||||
let base_dir = form_path.parent().unwrap_or_else(|| Path::new("."));
|
||||
|
||||
@ -286,6 +286,58 @@ fn detect_output_format(output_path: Option<&PathBuf>, default_format: &str) ->
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Load default values from a Nickel (.ncl) file
|
||||
///
|
||||
/// Exports the .ncl file to JSON, then extracts and flattens values
|
||||
/// matching the form fields.
|
||||
///
|
||||
/// Returns a HashMap of field names to their default values.
|
||||
fn load_nickel_defaults(
|
||||
ncl_path: &Path,
|
||||
form_elements: &[form_parser::FormElement],
|
||||
verbose: bool,
|
||||
) -> Result<std::collections::HashMap<String, serde_json::Value>> {
|
||||
use typedialog_core::nickel::NickelCli;
|
||||
|
||||
if verbose {
|
||||
eprintln!("[web] Loading default values from {}", ncl_path.display());
|
||||
}
|
||||
|
||||
NickelCli::verify()?;
|
||||
let value = NickelCli::export(ncl_path)?;
|
||||
|
||||
match value {
|
||||
serde_json::Value::Object(map) => {
|
||||
// Extract fields from elements (which includes fragments after expand_includes)
|
||||
let form_fields: Vec<form_parser::FieldDefinition> = form_elements
|
||||
.iter()
|
||||
.filter_map(|elem| match elem {
|
||||
form_parser::FormElement::Field(f) => Some(f.clone()),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Extract Nickel structure AND flatten everything (combine both approaches)
|
||||
let mut combined = extract_nickel_defaults(&map, &form_fields);
|
||||
let flattened = flatten_json_object(&map);
|
||||
|
||||
// Flattened values fill in gaps not covered by extraction
|
||||
for (k, v) in flattened {
|
||||
combined.entry(k).or_insert(v);
|
||||
}
|
||||
|
||||
if verbose {
|
||||
eprintln!("[web] Loaded {} default field values", combined.len());
|
||||
}
|
||||
|
||||
Ok(combined)
|
||||
}
|
||||
_ => Err(Error::validation_failed(
|
||||
"Defaults .ncl must export to a JSON object".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn execute_form(
|
||||
config: PathBuf,
|
||||
defaults: Option<PathBuf>,
|
||||
@ -314,44 +366,14 @@ async fn execute_form(
|
||||
let initial_values = if let Some(defaults_path_input) = defaults {
|
||||
// Resolve defaults path with cascading search
|
||||
let defaults_path = resolve_file_path(&defaults_path_input, base_dir, false);
|
||||
use typedialog_core::nickel::NickelCli;
|
||||
|
||||
let extension = defaults_path.extension().and_then(|s| s.to_str());
|
||||
let is_ncl = extension == Some("ncl");
|
||||
let is_toml = extension == Some("toml");
|
||||
|
||||
let defaults_json: std::collections::HashMap<String, serde_json::Value> = if is_ncl {
|
||||
// Convert .ncl to JSON using nickel export
|
||||
NickelCli::verify()?;
|
||||
let value = NickelCli::export(&defaults_path)?;
|
||||
match value {
|
||||
serde_json::Value::Object(map) => {
|
||||
// Extract fields from elements (which includes fragments after expand_includes)
|
||||
let form_fields: Vec<form_parser::FieldDefinition> = form
|
||||
.elements
|
||||
.iter()
|
||||
.filter_map(|elem| match elem {
|
||||
form_parser::FormElement::Field(f) => Some(f.clone()),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Extract Nickel structure AND flatten everything (combine both approaches)
|
||||
let mut combined = extract_nickel_defaults(&map, &form_fields);
|
||||
let flattened = flatten_json_object(&map);
|
||||
|
||||
// Flattened values fill in gaps not covered by extraction
|
||||
for (k, v) in flattened {
|
||||
combined.entry(k).or_insert(v);
|
||||
}
|
||||
combined
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::validation_failed(
|
||||
"Defaults .ncl must export to a JSON object".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
// Use helper function to load .ncl defaults
|
||||
load_nickel_defaults(&defaults_path, &form.elements, false)?
|
||||
} else if is_toml {
|
||||
// Read TOML and convert to JSON
|
||||
let defaults_content = fs::read_to_string(&defaults_path).map_err(|e| {
|
||||
@ -552,7 +574,14 @@ async fn nickel_roundtrip_cmd(
|
||||
form = form_parser::expand_includes(form, form_base_dir)
|
||||
.map_err(|e| Error::validation_failed(format!("Failed to expand includes: {}", e)))?;
|
||||
|
||||
// Step 3: Execute form with Web backend (interactive HTTP server)
|
||||
// Step 3: Load default values from input .ncl if exists
|
||||
let initial_values = if input.exists() {
|
||||
Some(load_nickel_defaults(&input, &form.elements, verbose)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Step 4: Execute form with Web backend (same path as normal execute_form)
|
||||
if verbose {
|
||||
eprintln!("[roundtrip] Starting HTTP server for interactive form");
|
||||
}
|
||||
@ -563,9 +592,16 @@ async fn nickel_roundtrip_cmd(
|
||||
println!("Starting interactive form on http://localhost:{}", port);
|
||||
println!("Complete the form and submit to continue...\n");
|
||||
|
||||
let form_results =
|
||||
form_parser::execute_with_backend_two_phase(form, backend.as_mut(), None, form_base_dir)
|
||||
.await?;
|
||||
// USE THE SAME EXECUTION PATH AS NORMAL WEB BACKEND
|
||||
// This respects display_mode and calls execute_form_complete() when display_mode = "complete"
|
||||
let form_results = form_parser::execute_with_backend_i18n_with_defaults(
|
||||
form,
|
||||
backend.as_mut(),
|
||||
None,
|
||||
form_base_dir,
|
||||
initial_values,
|
||||
)
|
||||
.await?;
|
||||
|
||||
if verbose {
|
||||
eprintln!(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user