use vize_l0::{Span, ToCompactString, id::NodeId};
use vize_l3::decision::vapor::{NativeTemplateVaporAnalysis, VaporUnsupported};
use crate::module::{AssemblyError, assemble_template_with_prelude};
use crate::runtime::{Runtime, vocabulary};
use crate::write::{Emitted, LinkSink, Writer};
mod component;
mod literal;
mod roots;
mod setup;
pub use component::emit_component;
pub use setup::emit_selected_setup_component;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VaporErrorKind {
Unsupported(VaporUnsupported),
MissingFacts,
ForeignRoot,
RuntimeHelper,
ScriptSource,
StyledSource,
ComponentFragmentLifecycle,
ComponentEmptySetupTemplate,
Assembly(AssemblyError),
Setup(crate::module::setup::SetupEmitError),
GeneratedBindingCollision,
Expression(crate::expr::EmitError),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct VaporError {
pub node: Option<NodeId>,
pub span: Span,
pub kind: VaporErrorKind,
}
pub fn emit_template<L: LinkSink>(
analysis: &NativeTemplateVaporAnalysis<'_, '_>,
) -> Result<Emitted<L>, VaporError> {
let (prelude, render) = fragments(analysis)?;
assemble_template_with_prelude(prelude, render, vocabulary(Runtime::VueVapor))
.map_err(|assembly| error(VaporErrorKind::Assembly(assembly)))
}
fn error(kind: VaporErrorKind) -> VaporError {
VaporError {
node: None,
span: Span::new(0, 0),
kind,
}
}
fn fragments<L: LinkSink>(
analysis: &NativeTemplateVaporAnalysis<'_, '_>,
) -> Result<(Writer<L>, Writer<L>), VaporError> {
let facts = analysis
.vapor()
.ok_or_else(|| error(VaporErrorKind::MissingFacts))?;
if let Some(rejection) = facts.unsupported().first() {
return Err(VaporError {
node: Some(rejection.node),
span: rejection.span,
kind: VaporErrorKind::Unsupported(rejection.reason),
});
}
let mut prelude = Writer::default();
let mut render = Writer::default();
render.push("function render(_ctx) {");
render.indent();
roots::static_roots(&mut prelude, &mut render, facts)?;
roots::return_roots(&mut render, facts.roots().len());
render.deindent();
render.newline();
render.push("}");
Ok((prelude, render))
}
fn number<L: LinkSink>(writer: &mut Writer<L>, value: usize) {
writer.push(value.to_compact_string().as_str());
}