use syntax::ast::Expression;
use crate::Renderer;
use crate::plan::bodies::LoweredStatement;
use crate::plan::values::{ValuePlan, setup_from_string};
use crate::utils::observable_after_mutation;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum CapturePolicy {
Never,
IfLaterSetup,
}
pub(crate) struct StagedExpression {
pub setup: Vec<LoweredStatement>,
pub value: String,
pub capture: CapturePolicy,
}
impl StagedExpression {
pub(crate) fn new(setup: String, value: String, expression: &Expression) -> Self {
let capture = if setup.is_empty() && observable_after_mutation(expression) {
CapturePolicy::IfLaterSetup
} else {
CapturePolicy::Never
};
Self {
setup: setup_from_string(setup),
value,
capture,
}
}
pub(crate) fn from_typed_setup(
setup: Vec<LoweredStatement>,
value: String,
expression: &Expression,
) -> Self {
let capture = if setup.is_empty() && observable_after_mutation(expression) {
CapturePolicy::IfLaterSetup
} else {
CapturePolicy::Never
};
Self {
setup,
value,
capture,
}
}
pub(crate) fn from_plan(plan: ValuePlan, expression: &Expression) -> Self {
match plan {
ValuePlan::Composite { setup, value } => Self {
setup,
value,
capture: CapturePolicy::Never,
},
ValuePlan::Operand(value) => {
let capture = if observable_after_mutation(expression) {
CapturePolicy::IfLaterSetup
} else {
CapturePolicy::Never
};
Self {
setup: Vec::new(),
value,
capture,
}
}
other => {
let mut setup = String::new();
let value = Renderer.render_value(&mut setup, &other);
Self::new(setup, value, expression)
}
}
}
}