fix(build): dispatch slot targets to matching component render/put
req: runtime/005 req: examples/001 req: htmx_equivalents/001
This commit is contained in:
+76
-22
@@ -539,16 +539,20 @@ impl Resources {
|
||||
));
|
||||
|
||||
// req: build/001 req: component/003
|
||||
let component_names: BTreeSet<String> = self.component_names().into_iter().collect();
|
||||
|
||||
if global_exports {
|
||||
self.push_component_refs(&mut out, 0);
|
||||
self.push_resource_modules(&mut out, None, 0);
|
||||
self.push_resource_modules(&mut out, &component_names, None, 0);
|
||||
}
|
||||
self.push_lowering_api(&mut out, None, 0);
|
||||
|
||||
for component in self.component_names() {
|
||||
out.push_str("\n#[allow(non_upper_case_globals)]\n");
|
||||
out.push_str(&format!("pub mod {component} {{\n"));
|
||||
self.push_resource_modules(&mut out, Some(&component), 1);
|
||||
out.push_str(" #[derive(Clone, Copy)]\n");
|
||||
out.push_str(" pub struct Component;\n\n");
|
||||
self.push_resource_modules(&mut out, &component_names, Some(&component), 1);
|
||||
self.push_lowering_api(&mut out, Some(&component), 1);
|
||||
out.push_str("}\n");
|
||||
}
|
||||
@@ -572,7 +576,13 @@ impl Resources {
|
||||
out.push_str(&format!("{pad}}}\n"));
|
||||
}
|
||||
|
||||
fn push_resource_modules(&self, out: &mut String, component: Option<&str>, indent: usize) {
|
||||
fn push_resource_modules(
|
||||
&self,
|
||||
out: &mut String,
|
||||
components: &BTreeSet<String>,
|
||||
component: Option<&str>,
|
||||
indent: usize,
|
||||
) {
|
||||
let pad = " ".repeat(indent);
|
||||
let inner = " ".repeat(indent + 1);
|
||||
let mut handle_ids = Vec::new();
|
||||
@@ -613,34 +623,53 @@ impl Resources {
|
||||
out.push_str(&format!(
|
||||
"{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod targets {{\n"
|
||||
));
|
||||
let child_prefix = if component.is_some() {
|
||||
"super::super::"
|
||||
} else {
|
||||
"super::"
|
||||
};
|
||||
out.push_str(&format!("{inner}#[derive(Clone, Copy)]\n"));
|
||||
out.push_str(&format!(
|
||||
"{inner}pub struct SlotTarget<T> {{ slot: ::hemx::advanced::Slot<T> }}\n"
|
||||
"{inner}pub struct SlotTarget<T, C = ()> {{ slot: ::hemx::advanced::Slot<T>, _marker: ::std::marker::PhantomData<C> }}\n"
|
||||
));
|
||||
out.push_str(&format!("{inner}#[allow(dead_code)]\n"));
|
||||
out.push_str(&format!("{inner}impl<T> SlotTarget<T> {{\n"));
|
||||
out.push_str(&format!("{inner} const fn new(slot: ::hemx::advanced::Slot<T>) -> Self {{ Self {{ slot }} }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn put(self, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ super::put(self.slot, view) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn replace(self, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ super::put(self.slot, view) }}\n"));
|
||||
out.push_str(&format!("{inner}impl<T, C> SlotTarget<T, C> {{\n"));
|
||||
out.push_str(&format!("{inner} const fn new(slot: ::hemx::advanced::Slot<T>) -> Self {{ Self {{ slot, _marker: ::std::marker::PhantomData }} }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn text(self, value: impl ::std::string::ToString) -> ::hemx::advanced::Effect {{ self.slot.text(value) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn set(self, value: impl ::std::string::ToString) -> ::hemx::advanced::Effect {{ self.slot.text(value) }}\n"));
|
||||
out.push_str(&format!("{inner}}}\n"));
|
||||
out.push_str(&format!("{inner}impl<T> SlotTarget<T, ()> {{\n"));
|
||||
out.push_str(&format!("{inner} pub fn put(self, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ super::put(self.slot, view) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn replace(self, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ super::put(self.slot, view) }}\n"));
|
||||
out.push_str(&format!("{inner}}}\n"));
|
||||
for res in self
|
||||
.slots
|
||||
.values()
|
||||
.filter(|res| component_matches(res, component))
|
||||
.filter(|res| components.contains(&res.ident) && Some(res.ident.as_str()) != component)
|
||||
{
|
||||
let child = &res.ident;
|
||||
out.push_str(&format!("{inner}impl<T> SlotTarget<T, {child_prefix}{child}::Component> {{\n"));
|
||||
out.push_str(&format!("{inner} pub fn put(self, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ {child_prefix}{child}::put(self.slot, view) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn replace(self, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ {child_prefix}{child}::put(self.slot, view) }}\n"));
|
||||
out.push_str(&format!("{inner}}}\n"));
|
||||
}
|
||||
out.push_str(&format!(
|
||||
"{inner}impl<T> ::hemx::GeneratedTarget for SlotTarget<T> {{\n"
|
||||
"{inner}impl<T, C> ::hemx::GeneratedTarget for SlotTarget<T, C> {{\n"
|
||||
));
|
||||
out.push_str(&format!("{inner} fn __hemx_resource_id(self) -> ::hemx::advanced::ResourceId {{ self.slot.id() }}\n"));
|
||||
out.push_str(&format!("{inner}}}\n"));
|
||||
out.push_str(&format!("{inner}#[derive(Clone, Copy)]\n"));
|
||||
out.push_str(&format!("{inner}pub struct KeyedSlotTarget<K, T> {{ slot: ::hemx::advanced::KeyedSlot<K, T> }}\n"));
|
||||
out.push_str(&format!("{inner}pub struct KeyedSlotTarget<K, T, C = ()> {{ slot: ::hemx::advanced::KeyedSlot<K, T>, _marker: ::std::marker::PhantomData<C> }}\n"));
|
||||
out.push_str(&format!("{inner}#[allow(dead_code)]\n"));
|
||||
out.push_str(&format!("{inner}impl<K, T> KeyedSlotTarget<K, T>\n"));
|
||||
out.push_str(&format!("{inner}impl<K, T, C> KeyedSlotTarget<K, T, C>\n"));
|
||||
out.push_str(&format!("{inner}where\n"));
|
||||
out.push_str(&format!("{inner} K: ::std::string::ToString,\n"));
|
||||
out.push_str(&format!("{inner}{{\n"));
|
||||
out.push_str(&format!("{inner} const fn new(slot: ::hemx::advanced::KeyedSlot<K, T>) -> Self {{ Self {{ slot }} }}\n"));
|
||||
out.push_str(&format!("{inner} const fn new(slot: ::hemx::advanced::KeyedSlot<K, T>) -> Self {{ Self {{ slot, _marker: ::std::marker::PhantomData }} }}\n"));
|
||||
out.push_str(&format!("{inner}}}\n"));
|
||||
out.push_str(&format!(
|
||||
"{inner}impl<T> KeyedSlotTarget<::std::string::String, T> {{\n"
|
||||
"{inner}impl<T> KeyedSlotTarget<::std::string::String, T, ()> {{\n"
|
||||
));
|
||||
out.push_str(&format!("{inner} pub fn append(self, view: impl ::hemplate::Hemplate + ::hemx::KeyedPartial) -> ::hemx::advanced::Effect {{ self.slot.append_html(view.hemx_key(), super::render(&view)) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn prepend(self, view: impl ::hemplate::Hemplate + ::hemx::KeyedPartial) -> ::hemx::advanced::Effect {{ self.slot.prepend_html(view.hemx_key(), super::render(&view)) }}\n"));
|
||||
@@ -650,8 +679,28 @@ impl Resources {
|
||||
out.push_str(&format!("{inner} pub fn replace_keyed(self, key: impl ::std::string::ToString, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ self.slot.replace_html(key.to_string(), super::render(view)) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn remove(self, key: impl ::std::string::ToString) -> ::hemx::advanced::Effect {{ self.slot.remove(key.to_string()) }}\n"));
|
||||
out.push_str(&format!("{inner}}}\n"));
|
||||
for res in self
|
||||
.slots
|
||||
.values()
|
||||
.filter(|res| component_matches(res, component))
|
||||
.filter(|res| res.keyed)
|
||||
.filter(|res| components.contains(&res.ident) && Some(res.ident.as_str()) != component)
|
||||
{
|
||||
let child = &res.ident;
|
||||
out.push_str(&format!(
|
||||
"{inner}impl<T> KeyedSlotTarget<::std::string::String, T, {child_prefix}{child}::Component> {{\n"
|
||||
));
|
||||
out.push_str(&format!("{inner} pub fn append(self, view: impl ::hemplate::Hemplate + ::hemx::KeyedPartial) -> ::hemx::advanced::Effect {{ self.slot.append_html(view.hemx_key(), {child_prefix}{child}::render(&view)) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn prepend(self, view: impl ::hemplate::Hemplate + ::hemx::KeyedPartial) -> ::hemx::advanced::Effect {{ self.slot.prepend_html(view.hemx_key(), {child_prefix}{child}::render(&view)) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn replace(self, view: impl ::hemplate::Hemplate + ::hemx::KeyedPartial) -> ::hemx::advanced::Effect {{ self.slot.replace_html(view.hemx_key(), {child_prefix}{child}::render(&view)) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn append_keyed(self, key: impl ::std::string::ToString, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ self.slot.append_html(key.to_string(), {child_prefix}{child}::render(view)) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn prepend_keyed(self, key: impl ::std::string::ToString, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ self.slot.prepend_html(key.to_string(), {child_prefix}{child}::render(view)) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn replace_keyed(self, key: impl ::std::string::ToString, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ self.slot.replace_html(key.to_string(), {child_prefix}{child}::render(view)) }}\n"));
|
||||
out.push_str(&format!("{inner} pub fn remove(self, key: impl ::std::string::ToString) -> ::hemx::advanced::Effect {{ self.slot.remove(key.to_string()) }}\n"));
|
||||
out.push_str(&format!("{inner}}}\n"));
|
||||
}
|
||||
out.push_str(&format!(
|
||||
"{inner}impl<K: ::std::string::ToString, T> ::hemx::GeneratedTarget for KeyedSlotTarget<K, T> {{\n"
|
||||
"{inner}impl<K: ::std::string::ToString, T, C> ::hemx::GeneratedTarget for KeyedSlotTarget<K, T, C> {{\n"
|
||||
));
|
||||
out.push_str(&format!("{inner} fn __hemx_resource_id(self) -> ::hemx::advanced::ResourceId {{ self.slot.id() }}\n"));
|
||||
out.push_str(&format!("{inner}}}\n"));
|
||||
@@ -660,14 +709,19 @@ impl Resources {
|
||||
.values()
|
||||
.filter(|res| component_matches(res, component))
|
||||
{
|
||||
let marker = if components.contains(&res.ident) && Some(res.ident.as_str()) != component {
|
||||
format!("{child_prefix}{}::Component", res.ident)
|
||||
} else {
|
||||
"()".to_string()
|
||||
};
|
||||
if res.keyed {
|
||||
out.push_str(&format!(
|
||||
"{inner}pub const {}: KeyedSlotTarget<::std::string::String, ::std::string::String> = KeyedSlotTarget::new(super::advanced::slots::{});\n",
|
||||
"{inner}pub const {}: KeyedSlotTarget<::std::string::String, ::std::string::String, {marker}> = KeyedSlotTarget::new(super::advanced::slots::{});\n",
|
||||
res.ident, res.ident
|
||||
));
|
||||
} else {
|
||||
out.push_str(&format!(
|
||||
"{inner}pub const {}: SlotTarget<::std::string::String> = SlotTarget::new(super::advanced::slots::{});\n",
|
||||
"{inner}pub const {}: SlotTarget<::std::string::String, {marker}> = SlotTarget::new(super::advanced::slots::{});\n",
|
||||
res.ident, res.ident
|
||||
));
|
||||
}
|
||||
@@ -2127,10 +2181,10 @@ mod tests {
|
||||
assert!(generated.contains("pub mod slots"));
|
||||
assert!(generated.contains("pub const todos"));
|
||||
assert!(generated.contains("pub mod targets"));
|
||||
assert!(generated.contains("pub struct SlotTarget<T>"));
|
||||
assert!(generated.contains("impl<T> ::hemx::GeneratedTarget for SlotTarget<T>"));
|
||||
assert!(generated.contains("pub struct SlotTarget<T, C = ()>"));
|
||||
assert!(generated.contains("impl<T, C> ::hemx::GeneratedTarget for SlotTarget<T, C>"));
|
||||
assert!(generated.contains(
|
||||
"impl<K: ::std::string::ToString, T> ::hemx::GeneratedTarget for KeyedSlotTarget<K, T>"
|
||||
"impl<K: ::std::string::ToString, T, C> ::hemx::GeneratedTarget for KeyedSlotTarget<K, T, C>"
|
||||
));
|
||||
assert!(generated.contains(
|
||||
"pub fn append(self, view: impl ::hemplate::Hemplate + ::hemx::KeyedPartial) -> ::hemx::advanced::Effect"
|
||||
@@ -2138,7 +2192,7 @@ mod tests {
|
||||
assert!(generated.contains(
|
||||
"pub fn append_keyed(self, key: impl ::std::string::ToString, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect"
|
||||
));
|
||||
assert!(generated.contains("pub const todos: SlotTarget<::std::string::String> = SlotTarget::new(super::advanced::slots::todos);"));
|
||||
assert!(generated.contains("pub const todos: SlotTarget<::std::string::String, ()> = SlotTarget::new(super::advanced::slots::todos);"));
|
||||
assert!(generated.contains("pub use self::targets::todos;"));
|
||||
assert!(generated.contains(
|
||||
"pub fn put(self, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect"
|
||||
@@ -2253,7 +2307,7 @@ mod tests {
|
||||
assert!(generated.contains("pub mod todo"));
|
||||
assert!(generated.contains("pub const create: ::hemx::Handle<()> = ::hemx::Handle::new("));
|
||||
assert!(generated.contains("pub const todos: ::hemx::advanced::Slot<::std::string::String> = ::hemx::advanced::Slot::new("));
|
||||
assert!(generated.contains("pub const todos: SlotTarget<::std::string::String> = SlotTarget::new(super::advanced::slots::todos);"));
|
||||
assert!(generated.contains("pub const todos: SlotTarget<::std::string::String, ()> = SlotTarget::new(super::advanced::slots::todos);"));
|
||||
assert!(generated.contains("pub use self::targets::todos;"));
|
||||
assert!(generated
|
||||
.contains("pub const click: ::hemx::EventName = ::hemx::EventName::new(\"click\")"));
|
||||
@@ -2301,7 +2355,7 @@ mod tests {
|
||||
assert!(generated.contains(" pub mod advanced"));
|
||||
assert!(generated.contains(" pub mod slots"));
|
||||
assert!(generated.contains(" pub mod targets"));
|
||||
assert!(generated.contains(" pub const todos: SlotTarget<::std::string::String> = SlotTarget::new(super::advanced::slots::todos);"));
|
||||
assert!(generated.contains(" pub const todos: SlotTarget<::std::string::String, ()> = SlotTarget::new(super::advanced::slots::todos);"));
|
||||
assert!(generated.contains(" pub use self::targets::todos;"));
|
||||
assert!(generated.contains(" #[doc(hidden)]\n pub fn lower_html"));
|
||||
assert!(generated.contains(
|
||||
|
||||
Reference in New Issue
Block a user