use crate::expr::JsExpr;
use crate::expr::js::JsCoordinateError;
use vize_l1::embed::syntax::EmbedHole;
use vize_l1::markup::{
NativeChild, NativeInterpolationOperand, NativeInterpolationView, NativeTemplateComponent,
};
mod transfer;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NativeInterpolationInputError {
UnadmittedOriginal,
Hole(EmbedHole),
Coordinates(JsCoordinateError),
}
pub struct NativeInterpolationInput<'a> {
operand: NativeInterpolationOperand<'a>,
expression: Option<&'a JsExpr<'a>>,
}
impl<'a> NativeInterpolationInput<'a> {
#[must_use]
pub const fn from_operand(operand: NativeInterpolationOperand<'a>) -> Self {
Self {
operand,
expression: None,
}
}
#[must_use]
pub const fn operand(&self) -> &NativeInterpolationOperand<'a> {
&self.operand
}
pub fn admitted_for<'s>(
&'s mut self,
selected: &'s NativeTemplateComponent<'a>,
child: NativeChild<'s, 'a>,
) -> Result<NativeInterpolationInputView<'s, 'a>, NativeInterpolationInputError> {
if let Some(hole) = self.operand.syntax().hole() {
return Err(NativeInterpolationInputError::Hole(hole));
}
let original = self
.operand
.admitted_for(selected, child)
.ok_or(NativeInterpolationInputError::UnadmittedOriginal)?;
let expression = if let Some(expression) = self.expression {
expression
} else {
let expression =
transfer::retain(&original).map_err(NativeInterpolationInputError::Coordinates)?;
self.expression = Some(expression);
expression
};
Ok(NativeInterpolationInputView {
input: self,
original,
expression,
})
}
}
pub struct NativeInterpolationInputView<'s, 'a> {
input: &'s NativeInterpolationInput<'a>,
original: NativeInterpolationView<'s, 'a>,
expression: &'a JsExpr<'a>,
}
impl<'s, 'a> NativeInterpolationInputView<'s, 'a> {
#[must_use]
pub const fn input(&self) -> &'s NativeInterpolationInput<'a> {
self.input
}
#[must_use]
pub const fn original(&self) -> &NativeInterpolationView<'s, 'a> {
&self.original
}
#[must_use]
pub const fn expression(&self) -> &'a JsExpr<'a> {
self.expression
}
}
#[cfg(test)]
mod tests;