use compact_str::ToCompactString;
use lashlang::{
AbilityOp, AbilityResult, ExecutionHost, ExecutionHostError, HostDescriptor, ImageValue,
LASH_PROCESS_NAME_KEY, LashlangAbilities, LashlangHostCatalog, LashlangHostEnvironment,
LinkedModule, ListValue, ProjectedBindings, ProjectedFuture, ProjectedHostDescriptor,
ProjectedReadRequest, ProjectedReadResponse, ProjectedValue, Record, State, TypeExpr,
TypeField, Value, from_json,
};
use std::fmt;
use std::sync::{Arc, OnceLock};
#[derive(Clone, Copy, Debug)]
pub enum Scenario {
Baseline,
LanguageHostEnvironment,
AsyncAwait,
DirectUnwrap,
GeneralFanout,
LoopControl,
IndexedAssignment,
ProjectedValues,
LargeData,
CachePressure,
ProjectedOperations,
TypeSystemStress,
WrappedErrorPaths,
ToolControlHostEnvironment,
SnapshotProjectedState,
ContinueAsSeedHostEnvironment,
TriggerRegistryHostEnvironment,
SyntaxTextHostEnvironment,
IntegerRangeHostEnvironment,
FanoutExpressionHostEnvironment,
ImageHostEnvironment,
}
impl Scenario {
pub const ALL: &'static [Self] = &[
Self::Baseline,
Self::LanguageHostEnvironment,
Self::AsyncAwait,
Self::DirectUnwrap,
Self::GeneralFanout,
Self::LoopControl,
Self::IndexedAssignment,
Self::ProjectedValues,
Self::LargeData,
Self::CachePressure,
Self::ProjectedOperations,
Self::TypeSystemStress,
Self::WrappedErrorPaths,
Self::ToolControlHostEnvironment,
Self::SnapshotProjectedState,
Self::ContinueAsSeedHostEnvironment,
Self::TriggerRegistryHostEnvironment,
Self::SyntaxTextHostEnvironment,
Self::IntegerRangeHostEnvironment,
Self::FanoutExpressionHostEnvironment,
Self::ImageHostEnvironment,
];
#[allow(dead_code)]
pub fn parse(value: &str) -> Option<Self> {
Some(match value {
"baseline" => Self::Baseline,
"language_host_environment" => Self::LanguageHostEnvironment,
"async_await" => Self::AsyncAwait,
"direct_unwrap" => Self::DirectUnwrap,
"general_fanout" => Self::GeneralFanout,
"loop_control" => Self::LoopControl,
"indexed_assignment" => Self::IndexedAssignment,
"projected_values" => Self::ProjectedValues,
"large_data" => Self::LargeData,
"cache_pressure" => Self::CachePressure,
"projected_operations" => Self::ProjectedOperations,
"type_system_stress" => Self::TypeSystemStress,
"wrapped_error_paths" => Self::WrappedErrorPaths,
"tool_control_host_environment" => Self::ToolControlHostEnvironment,
"snapshot_projected_state" => Self::SnapshotProjectedState,
"continue_as_seed_host_environment" => Self::ContinueAsSeedHostEnvironment,
"trigger_registry_host_environment" => Self::TriggerRegistryHostEnvironment,
"syntax_text_host_environment" => Self::SyntaxTextHostEnvironment,
"integer_range_host_environment" => Self::IntegerRangeHostEnvironment,
"fanout_expression_host_environment" => Self::FanoutExpressionHostEnvironment,
"image_host_environment" => Self::ImageHostEnvironment,
_ => return None,
})
}
#[allow(dead_code)]
pub fn expected_values() -> &'static str {
"baseline, language_host_environment, async_await, direct_unwrap, general_fanout, loop_control, indexed_assignment, projected_values, large_data, cache_pressure, projected_operations, type_system_stress, wrapped_error_paths, tool_control_host_environment, snapshot_projected_state, continue_as_seed_host_environment, trigger_registry_host_environment, syntax_text_host_environment, integer_range_host_environment, fanout_expression_host_environment, image_host_environment, or all"
}
}
impl fmt::Display for Scenario {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Baseline => "baseline",
Self::LanguageHostEnvironment => "language_host_environment",
Self::AsyncAwait => "async_await",
Self::DirectUnwrap => "direct_unwrap",
Self::GeneralFanout => "general_fanout",
Self::LoopControl => "loop_control",
Self::IndexedAssignment => "indexed_assignment",
Self::ProjectedValues => "projected_values",
Self::LargeData => "large_data",
Self::CachePressure => "cache_pressure",
Self::ProjectedOperations => "projected_operations",
Self::TypeSystemStress => "type_system_stress",
Self::WrappedErrorPaths => "wrapped_error_paths",
Self::ToolControlHostEnvironment => "tool_control_host_environment",
Self::SnapshotProjectedState => "snapshot_projected_state",
Self::ContinueAsSeedHostEnvironment => "continue_as_seed_host_environment",
Self::TriggerRegistryHostEnvironment => "trigger_registry_host_environment",
Self::SyntaxTextHostEnvironment => "syntax_text_host_environment",
Self::IntegerRangeHostEnvironment => "integer_range_host_environment",
Self::FanoutExpressionHostEnvironment => "fanout_expression_host_environment",
Self::ImageHostEnvironment => "image_host_environment",
})
}
}
#[allow(dead_code)]
pub fn seeded_state() -> State {
seeded_state_for(Scenario::Baseline)
}
pub fn seeded_state_for(scenario: Scenario) -> State {
let mut globals = Record::default();
globals.insert(
"history".to_string(),
Value::List(
vec![
Value::String("alpha".to_string().into()),
Value::String("beta".to_string().into()),
Value::String("gamma".to_string().into()),
]
.into(),
),
);
globals.insert(
"ctx".to_string(),
Value::Record({
let mut record = Record::default();
record.insert("user".to_string(), Value::String("sam".into()));
record.insert("attempt".to_string(), Value::Number(3.0));
record.into()
}),
);
if matches!(scenario, Scenario::SnapshotProjectedState) {
globals.insert("snap".to_string(), snapshot_projected_record());
}
if matches!(scenario, Scenario::ImageHostEnvironment) {
globals.insert(
"img".to_string(),
Value::Image(ImageValue::new(
"img-1",
"chart.png",
1234,
Some(640),
Some(480),
)),
);
}
State::from_snapshot(lashlang::Snapshot { globals })
}
include!("sections/program.rs");
include!("sections/environment.rs");
include!("sections/projected.rs");
include!("sections/host.rs");