#![ allow( clippy::needless_pass_by_value ) ]
use unilang::semantic::VerifiedCommand;
use unilang::data::{ OutputData, ErrorData };
use unilang::interpreter::ExecutionContext;
use core::fmt::Write as _;
#[ allow( clippy::too_many_lines ) ]
pub fn info_handler(
cmd : VerifiedCommand,
_ctx : ExecutionContext
) -> Result< OutputData, ErrorData >
{
let verbosity = cmd.get_integer( "verbosity" ).unwrap_or( 1 );
let archive = crate::handlers::shared_state::get_current_archive()
.ok_or_else( || crate::error::state_error( "No archive loaded. Use .archive.load first." ) )?;
let file_count = archive.file_count();
let text_count = archive.text_file_count();
let binary_count = archive.binary_file_count();
let total_size = archive.total_size();
let param_count = archive.parameters.descriptors.len();
let output_content = match verbosity
{
0 => String::new(),
1 =>
{
format!(
"Archive: {}\nFiles: {} ({} text, {} binary)\nSize: {} bytes\nParameters: {}",
archive.name,
file_count,
text_count,
binary_count,
total_size,
param_count
)
}
_ =>
{
let mut details = format!(
"Archive Information\n\
==================\n\
Name: {}\n\
Version: {}\n",
archive.name,
archive.version
);
if let Some( ref desc ) = archive.description
{
let _ = writeln!( &mut details, "Description: {desc}" );
}
let _ = write!(
&mut details,
"\nStatistics\n\
----------\n\
Total Files: {file_count}\n\
Text Files: {text_count}\n\
Binary Files: {binary_count}\n\
Total Size: {total_size} bytes\n\
Parameters Defined: {param_count}\n"
);
if verbosity >= 3 && !archive.files.is_empty()
{
details.push_str( "\nFiles\n-----\n" );
for file in &archive.files
{
let _ = writeln!( &mut details, " {}", file.path.display() );
}
}
details
}
};
Ok( OutputData
{
content : output_content,
format : "text".to_string(),
execution_time_ms : None,
} )
}
#[ allow( clippy::too_many_lines ) ]
pub fn discover_parameters_handler(
cmd : VerifiedCommand,
_ctx : ExecutionContext
) -> Result< OutputData, ErrorData >
{
let verbosity = cmd.get_integer( "verbosity" ).unwrap_or( 1 );
let archive = crate::handlers::shared_state::get_current_archive()
.ok_or_else( || crate::error::state_error( "No archive loaded. Use .archive.load first." ) )?;
let discovered = archive.discover_parameters();
let param_count = discovered.len();
let mut params : Vec< String > = discovered.into_iter().collect();
params.sort();
let output_content = match verbosity
{
0 => String::new(),
1 =>
{
if param_count == 0
{
"No parameters discovered".to_string()
}
else
{
format!( "Discovered {} parameters: {}", param_count, params.join( ", " ) )
}
}
_ =>
{
let mut details = format!(
"Parameter Discovery\n\
===================\n\
Found: {param_count} parameters\n"
);
if !params.is_empty()
{
details.push_str( "\nDiscovered Parameters\n---------------------\n" );
for param in ¶ms
{
let _ = writeln!( &mut details, " - {param}" );
}
}
if verbosity >= 3 && !params.is_empty()
{
let usage = archive.analyze_parameter_usage();
details.push_str( "\nParameter Usage\n---------------\n" );
for param in ¶ms
{
if let Some( files ) = usage.get( param )
{
let _ = writeln!( &mut details, " {} (used in {} files)", param, files.len() );
if verbosity >= 4
{
for file in files
{
let _ = writeln!( &mut details, " - {}", file.display() );
}
}
}
}
}
details
}
};
Ok( OutputData
{
content : output_content,
format : "text".to_string(),
execution_time_ms : None,
} )
}
#[ allow( clippy::too_many_lines ) ]
pub fn status_handler(
cmd : VerifiedCommand,
_ctx : ExecutionContext
) -> Result< OutputData, ErrorData >
{
let verbosity = cmd.get_integer( "verbosity" ).unwrap_or( 1 );
let archive = crate::handlers::shared_state::get_current_archive()
.ok_or_else( || crate::error::state_error( "No archive loaded. Use .archive.load first." ) )?;
let mandatory_params = archive.parameters.list_mandatory();
let defined_params = archive.parameters.descriptors.len();
let set_values = archive.values.as_ref().map_or( 0, genfile_core::Values::len );
let missing_mandatory : Vec< &str > = mandatory_params
.iter()
.filter( | p |
{
archive
.values
.as_ref()
.is_none_or( | v | !v.has_value( p ) )
})
.copied()
.collect();
let ready = missing_mandatory.is_empty();
let output_content = match verbosity
{
0 => String::new(),
1 =>
{
if ready
{
format!( "Status: Ready to materialize ({set_values} parameters set)" )
}
else
{
format!(
"Status: Not ready - {} mandatory parameters missing: {}",
missing_mandatory.len(),
missing_mandatory.join( ", " )
)
}
}
_ =>
{
let mut details = format!(
"Archive Status\n\
==============\n\
Archive: {}\n\
Files: {}\n\
Parameters Defined: {}\n\
Values Set: {}\n\
Mandatory Parameters: {}\n",
archive.name,
archive.file_count(),
defined_params,
set_values,
mandatory_params.len()
);
if ready
{
details.push_str( "\nReadiness: ✓ Ready to materialize\n" );
}
else
{
details.push_str( "\nReadiness: ✗ Not ready\n" );
details.push_str( "\nMissing Mandatory Values\n------------------------\n" );
for param in &missing_mandatory
{
let _ = writeln!( &mut details, " - {param}" );
}
}
if verbosity >= 3 && defined_params > 0
{
details.push_str( "\nDefined Parameters\n------------------\n" );
for param_desc in &archive.parameters.descriptors
{
let mandatory_marker = if param_desc.is_mandatory { " (mandatory)" } else { "" };
let has_value = archive
.values
.as_ref()
.is_some_and( | v | v.has_value( ¶m_desc.parameter ) );
let value_marker = if has_value { " [set]" } else { "" };
let _ = writeln!(
&mut details,
" - {}{}{}",
param_desc.parameter,
mandatory_marker,
value_marker
);
}
}
details
}
};
Ok( OutputData
{
content : output_content,
format : "text".to_string(),
execution_time_ms : None,
} )
}
#[ allow( clippy::too_many_lines ) ]
pub fn analyze_handler(
cmd : VerifiedCommand,
_ctx : ExecutionContext
) -> Result< OutputData, ErrorData >
{
let verbosity = cmd.get_integer( "verbosity" ).unwrap_or( 1 );
let archive = crate::handlers::shared_state::get_current_archive()
.ok_or_else( || crate::error::state_error( "No archive loaded. Use .archive.load first." ) )?;
let file_count = archive.file_count();
let text_count = archive.text_file_count();
let binary_count = archive.binary_file_count();
let total_size = archive.total_size();
let discovered = archive.discover_parameters();
let defined_params = archive.parameters.descriptors.len();
let mandatory_params = archive.parameters.list_mandatory();
let set_values = archive.values.as_ref().map_or( 0, genfile_core::Values::len );
let missing_mandatory : Vec< &str > = mandatory_params
.iter()
.filter( | p |
{
archive
.values
.as_ref()
.is_none_or( | v | !v.has_value( p ) )
})
.copied()
.collect();
let ready = missing_mandatory.is_empty();
let output_content = match verbosity
{
0 => String::new(),
1 =>
{
format!(
"Archive Analysis Summary\n\
Archive: {}\n\
Files: {} ({} text, {} binary, {} bytes)\n\
Parameters: {} defined, {} discovered\n\
Status: {}",
archive.name,
file_count,
text_count,
binary_count,
total_size,
defined_params,
discovered.len(),
if ready { "Ready to materialize" } else { "Not ready (missing mandatory values)" }
)
}
_ =>
{
let mut details = format!(
"Comprehensive Archive Analysis\n\
==============================\n\
\n\
Archive Metadata\n\
----------------\n\
Name: {}\n\
Version: {}\n",
archive.name,
archive.version
);
if let Some( ref desc ) = archive.description
{
let _ = writeln!( &mut details, "Description: {desc}" );
}
let _ = write!(
&mut details,
"\nFile Statistics\n\
---------------\n\
Total Files: {file_count}\n\
Text Files: {text_count}\n\
Binary Files: {binary_count}\n\
Total Size: {total_size} bytes\n"
);
let _ = write!(
&mut details,
"\nParameter Analysis\n\
------------------\n\
Discovered in Templates: {}\n\
Defined: {}\n\
Mandatory: {}\n\
Values Set: {}\n",
discovered.len(),
defined_params,
mandatory_params.len(),
set_values
);
if ready
{
details.push_str( "\nReadiness Status\n----------------\n✓ Ready to materialize\n" );
}
else
{
let _ = write!(
&mut details,
"\nReadiness Status\n\
----------------\n\
✗ Not ready\n\
Missing mandatory values: {}\n",
missing_mandatory.join( ", " )
);
}
if verbosity >= 3
{
let mut discovered_vec : Vec< String > = discovered.into_iter().collect();
discovered_vec.sort();
if !discovered_vec.is_empty()
{
details.push_str( "\nDiscovered Parameters\n---------------------\n" );
for param in &discovered_vec
{
let _ = writeln!( &mut details, " - {param}" );
}
}
if !archive.files.is_empty()
{
details.push_str( "\nArchive Files\n-------------\n" );
for file in &archive.files
{
let _ = writeln!( &mut details, " {}", file.path.display() );
}
}
}
details
}
};
Ok( OutputData
{
content : output_content,
format : "text".to_string(),
execution_time_ms : None,
} )
}