use core::fmt::{Result, Write};
use super::{Style, end_line, indent, print_expr, print_name, quoted};
use crate::dump::owned::{
Attribute, Bind, Binding, On, SlotContent, VueCloak, VueCssBind, VueDirective, VueHtml,
VueMemo, VueOnce, VueShow, VueSlotScope, VueSync, VueText,
};
use vize_l0::String;
pub(super) fn print_attribute<W: Write>(
w: &mut W,
attribute: &Attribute,
depth: usize,
mode: Style,
) -> Result {
indent(w, depth)?;
w.write_str("attr ")?;
let name = attribute.name.as_str();
if name.contains(['=', '"']) || name.chars().any(char::is_whitespace) {
quoted(w, name)?;
} else {
w.write_str(name)?;
}
if let Some(value) = &attribute.value {
w.write_char('=')?;
quoted(w, value.as_str())?;
}
end_line(w, attribute.span, mode)
}
pub(super) fn print_binding<W: Write>(
w: &mut W,
binding: &Binding,
depth: usize,
mode: Style,
) -> Result {
match binding {
Binding::Bind(bind) => print_bind(w, bind, depth, mode),
Binding::On(on) => print_on(w, on, depth, mode),
Binding::Model(model) => {
indent(w, depth)?;
w.write_str("ui.model")?;
if let Some(argument) = &model.argument {
w.write_str(" name=")?;
print_name(w, argument, mode)?;
}
w.write_str(" read=")?;
print_expr(w, &model.contract.read, mode)?;
w.write_str(" write=")?;
print_expr(w, &model.contract.write, mode)?;
end_line(w, model.span, mode)?;
for attribute in &model.attributes {
print_attribute(w, attribute, depth + 1, mode)?;
}
Ok(())
}
Binding::SlotContent(content) => print_slot_content(w, content, depth, mode),
Binding::SlotsObject(object) => {
indent(w, depth)?;
match mode.grammar {
crate::dump::codec::Grammar::CurrentV2 => w.write_str("ui.slots-object value=")?,
crate::dump::codec::Grammar::HistoricalV1 => {
w.write_str("vue.directive \"slots\" value=")?
}
}
print_expr(w, &object.value, mode)?;
end_line(w, object.span, mode)
}
Binding::VueDirective(directive) => print_directive(w, directive, depth, mode),
Binding::VueCssBind(bind) => print_css_bind(w, bind, depth, mode),
Binding::VueSync(sync) => print_sync(w, sync, depth, mode),
Binding::VueSlotScope(scope) => print_slot_scope(w, scope, depth, mode),
Binding::VueOnce(once) => print_once(w, once, depth, mode),
Binding::VueMemo(memo) => print_memo(w, memo, depth, mode),
Binding::VueShow(show) => print_show(w, show, depth, mode),
Binding::VueHtml(html) => print_html(w, html, depth, mode),
Binding::VueText(text) => print_vue_text(w, text, depth, mode),
Binding::VueCloak(cloak) => print_cloak(w, cloak, depth, mode),
}
}
fn print_mods<W: Write>(w: &mut W, modifiers: &[String]) -> Result {
if modifiers.is_empty() {
return Ok(());
}
if modifiers
.iter()
.all(|modifier| !modifier.as_str().contains([',', '"', '\\', '\n', '\r']))
{
w.write_str(" mods=\"")?;
for (i, modifier) in modifiers.iter().enumerate() {
if i > 0 {
w.write_char(',')?;
}
w.write_str(modifier.as_str())?;
}
return w.write_char('"');
}
w.write_str(" mods=[")?;
for (i, modifier) in modifiers.iter().enumerate() {
if i > 0 {
w.write_char(',')?;
}
quoted(w, modifier.as_str())?;
}
w.write_char(']')
}
fn print_bind<W: Write>(w: &mut W, bind: &Bind, depth: usize, mode: Style) -> Result {
indent(w, depth)?;
w.write_str("ui.bind")?;
if let Some(name) = &bind.name {
w.write_str(" name=")?;
print_name(w, name, mode)?;
}
print_mods(w, &bind.modifiers)?;
if let Some(value) = &bind.value {
w.write_str(" value=")?;
print_expr(w, value, mode)?;
}
end_line(w, bind.span, mode)
}
fn print_on<W: Write>(w: &mut W, on: &On, depth: usize, mode: Style) -> Result {
indent(w, depth)?;
w.write_str("ui.on")?;
if let Some(name) = &on.name {
w.write_str(" name=")?;
print_name(w, name, mode)?;
}
print_mods(w, &on.modifiers)?;
if let Some(handler) = &on.handler {
w.write_str(" handler=")?;
print_expr(w, handler, mode)?;
}
if let Some(id) = on.native_handler {
write!(w, " handler-ref={id}")?;
}
end_line(w, on.span, mode)
}
fn print_slot_content<W: Write>(
w: &mut W,
content: &SlotContent,
depth: usize,
mode: Style,
) -> Result {
indent(w, depth)?;
w.write_str("ui.slot-content")?;
if let Some(name) = &content.name {
w.write_str(" name=")?;
print_name(w, name, mode)?;
}
print_mods(w, &content.modifiers)?;
if let Some(params) = &content.params {
w.write_str(" params=")?;
print_expr(w, params, mode)?;
}
end_line(w, content.span, mode)
}
fn print_directive<W: Write>(
w: &mut W,
directive: &VueDirective,
depth: usize,
mode: Style,
) -> Result {
indent(w, depth)?;
w.write_str("vue.directive ")?;
quoted(w, directive.name.as_str())?;
if let Some(argument) = &directive.argument {
w.write_str(" arg=")?;
print_name(w, argument, mode)?;
}
print_mods(w, &directive.modifiers)?;
if let Some(value) = &directive.value {
w.write_str(" value=")?;
print_expr(w, value, mode)?;
}
end_line(w, directive.span, mode)
}
fn print_css_bind<W: Write>(w: &mut W, bind: &VueCssBind, depth: usize, mode: Style) -> Result {
indent(w, depth)?;
w.write_str("vue.css-bind value=")?;
print_expr(w, &bind.value, mode)?;
end_line(w, bind.span, mode)
}
fn print_sync<W: Write>(w: &mut W, sync: &VueSync, depth: usize, mode: Style) -> Result {
indent(w, depth)?;
w.write_str("vue.sync name=")?;
quoted(w, sync.name.as_str())?;
print_mods(w, &sync.modifiers)?;
w.write_str(" value=")?;
print_expr(w, &sync.value, mode)?;
end_line(w, sync.span, mode)
}
fn print_slot_scope<W: Write>(
w: &mut W,
scope: &VueSlotScope,
depth: usize,
mode: Style,
) -> Result {
indent(w, depth)?;
w.write_str("vue.slot-scope")?;
if let Some(name) = &scope.name {
w.write_str(" name=")?;
quoted(w, name.as_str())?;
}
if let Some(params) = &scope.params {
w.write_str(" params=")?;
print_expr(w, params, mode)?;
}
end_line(w, scope.span, mode)
}
fn print_once<W: Write>(w: &mut W, once: &VueOnce, depth: usize, mode: Style) -> Result {
indent(w, depth)?;
w.write_str("vue.once")?;
end_line(w, once.span, mode)
}
fn print_memo<W: Write>(w: &mut W, memo: &VueMemo, depth: usize, mode: Style) -> Result {
indent(w, depth)?;
w.write_str("vue.memo value=")?;
print_expr(w, &memo.value, mode)?;
end_line(w, memo.span, mode)
}
fn print_show<W: Write>(w: &mut W, show: &VueShow, depth: usize, mode: Style) -> Result {
indent(w, depth)?;
w.write_str("vue.show value=")?;
print_expr(w, &show.value, mode)?;
end_line(w, show.span, mode)
}
fn print_html<W: Write>(w: &mut W, html: &VueHtml, depth: usize, mode: Style) -> Result {
indent(w, depth)?;
w.write_str("vue.html")?;
if let Some(value) = &html.value {
w.write_str(" value=")?;
print_expr(w, value, mode)?;
}
end_line(w, html.span, mode)
}
fn print_vue_text<W: Write>(w: &mut W, text: &VueText, depth: usize, mode: Style) -> Result {
indent(w, depth)?;
w.write_str("vue.text")?;
if let Some(value) = &text.value {
w.write_str(" value=")?;
print_expr(w, value, mode)?;
}
end_line(w, text.span, mode)
}
fn print_cloak<W: Write>(w: &mut W, cloak: &VueCloak, depth: usize, mode: Style) -> Result {
indent(w, depth)?;
w.write_str("vue.cloak")?;
end_line(w, cloak.span, mode)
}