feat: finalize the Hemx 0.4 core
CI / test (push) Has been cancelled

This commit is contained in:
tmk241
2026-09-02 17:28:40 +02:00
parent 1dc9734f16
commit a3c72e21db
15 changed files with 96 additions and 231 deletions
-54
View File
@@ -17,7 +17,6 @@ pub(super) struct Resources {
pub(super) handle_forms: BTreeMap<String, String>,
pub(super) handle_params: BTreeMap<String, BTreeSet<String>>,
pub(super) forms: BTreeMap<String, FormResource>,
pub(super) atoms: BTreeMap<String, Resource>,
pub(super) classes: BTreeMap<String, ClassToken>,
pub(super) events: BTreeMap<String, EventToken>,
}
@@ -101,12 +100,6 @@ impl Resources {
self.insert_slot(canonical, name, component.clone(), keyed)?;
}
if let Some(name) = static_attr(&node.attrs, "data-hemx-atom") {
reject_unkeyed_loop(surface, node.scope, path, "atom", &name)?;
let canonical = canonical_symbol(root, path, &name);
self.insert_atom(canonical, name, component.clone())?;
}
if let Some(name) = static_attr(&node.attrs, "data-hemx-handle") {
reject_unkeyed_loop(surface, node.scope, path, "handle", &name)?;
let canonical = canonical_symbol(root, path, &name);
@@ -169,15 +162,6 @@ impl Resources {
insert_resource(&mut self.handles, "handle", symbol, name, component).map(|_| ())
}
pub(super) fn insert_atom(
&mut self,
symbol: String,
name: String,
component: String,
) -> io::Result<()> {
insert_resource(&mut self.atoms, "atom", symbol, name, component).map(|_| ())
}
pub(super) fn insert_class(
&mut self,
symbol: String,
@@ -576,21 +560,6 @@ impl Resources {
}
out.push_str(&format!("{pad}}}\n\n"));
out.push_str(&format!(
"{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod atoms {{\n"
));
for res in self
.atoms
.values()
.filter(|res| component_matches(res, component))
{
out.push_str(&format!(
"{inner}pub const {}: ::hemx::Atom<::std::string::String> = ::hemx::Atom::new({});\n",
res.ident, res.id
));
}
out.push_str(&format!("{pad}}}\n\n"));
out.push_str(&format!(
"{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod classes {{\n"
));
@@ -794,17 +763,6 @@ impl Resources {
res.id
));
}
for res in self
.atoms
.values()
.filter(|res| component_matches(res, component))
{
out.push_str(&format!(
"{pad} (\"data-hemx-atom\", {}, {}),\n",
rust_str(&res.ident),
res.id
));
}
out.push_str(&format!("{pad}];\n"));
}
@@ -818,7 +776,6 @@ fn __hemx_lower_html(html: &str, table: &[(&str, &str, u32)]) -> ::std::string::
"data-hemx-handle" => "data-hemx-action",
"data-hemx-form" => "data-hemx-resource",
"data-hemx-revealed" => "data-hemx-revealed",
"data-hemx-atom" => "data-hemx-resource",
_ => continue,
};
out = __hemx_replace_attr(out, attr, name, runtime_attr, *id);
@@ -899,7 +856,6 @@ fn __hemx_attr(tag: &str, attr: &str) -> Option<::std::string::String> {
.values()
.map(|res| &res.component)
.chain(self.handles.values().map(|res| &res.component))
.chain(self.atoms.values().map(|res| &res.component))
.chain(self.forms.values().map(|form| &form.resource.component))
.chain(self.classes.values().map(|class| &class.component))
.chain(self.events.values().map(|event| &event.component))
@@ -955,12 +911,6 @@ fn __hemx_attr(tag: &str, attr: &str) -> Option<::std::string::String> {
out.push_str(&format!("handle_param\t{handle_ident}\t{param}\n"));
}
}
for res in self.atoms.values() {
out.push_str(&format!(
"atom\t{}\t{}\t{}\n",
res.symbol, res.ident, res.id
));
}
for class in self.classes.values() {
out.push_str(&format!(
"class\t{}\t{}\t{}\n",
@@ -991,10 +941,6 @@ fn __hemx_attr(tag: &str, attr: &str) -> Option<::std::string::String> {
parts.push(1);
parts.push(res.id);
}
for res in self.atoms.values() {
parts.push(3);
parts.push(res.id);
}
for form in self.forms.values() {
parts.push(2);
parts.push(form.resource.id);
-2
View File
@@ -42,11 +42,9 @@ pub(super) fn known_hemx_attr(name: &str) -> bool {
"data-hemx-root"
| "data-hemx-sse"
| "data-hemx-ws"
| "data-hemx-st"
| "data-hemx-handle"
| "data-hemx-slot"
| "data-hemx-form"
| "data-hemx-atom"
| "data-hemx-key"
| "data-hemx-on"
| "data-hemx-pending-class"
+7 -35
View File
@@ -589,10 +589,9 @@ mod tests {
io::ErrorKind::InvalidData
);
for (kind, source) in [
("atom", r#"<span data-hemx-atom="shared"></span>"#),
("handle", r#"<button data-hemx-handle="shared"></button>"#),
] {
let kind = "handle";
let source = r#"<button data-hemx-handle="shared"></button>"#;
{
let first =
surface_for_heml_source(Path::new("first.heml"), source.to_owned()).unwrap();
let second =
@@ -663,9 +662,6 @@ mod tests {
resources
.handles
.insert("save".into(), resource("save", "page", 12));
resources
.atoms
.insert("count".into(), resource("count", "page", 13));
resources.forms.insert(
"profile".into(),
FormResource {
@@ -693,8 +689,6 @@ mod tests {
11,
1,
12,
3,
13,
2,
14,
2,
@@ -713,7 +707,6 @@ mod tests {
));
assert!(generated.contains("pub const slot: SlotTarget"));
assert!(generated.contains("pub const save: ::hemx::Handle"));
assert!(generated.contains("pub const count: ::hemx::Atom"));
assert!(generated.contains("pub const profile: ::hemx::Form"));
assert!(generated.contains("\n pub mod targets {\n"));
@@ -727,9 +720,6 @@ mod tests {
resources
.handles
.insert("edit".into(), resource("edit", "row", 22));
resources
.atoms
.insert("selection".into(), resource("selection", "row", 23));
resources
.slots
.insert("child".into(), resource("child", "page", 24));
@@ -788,17 +778,17 @@ mod tests {
let canonical_syms = resources.syms();
assert_eq!(
stable_id("generated-rs", &canonical_generated),
3_787_638_288,
2_865_325_407,
"canonical generated Rust changed"
);
assert_eq!(
stable_id("generated-rs-global", &canonical_globals),
1_112_484_789,
3_814_759_598,
"canonical global-export Rust changed"
);
assert_eq!(
stable_id("generated-syms", &canonical_syms),
984_222_700,
2_299_561_723,
"canonical symbol manifest changed"
);
}
@@ -1090,7 +1080,7 @@ mod tests {
std::fs::create_dir_all(&templates).unwrap();
std::fs::write(
templates.join("todo.heml"),
r#"<form class="todo-card" data-hemx-handle="create" data-hemx-form="new_todo"><input name="title" required><select name="labels" multiple><option value="urgent">Urgent</option></select><input name="__h" value="reserved"></form><button data-hemx-handle="delete" data-todo-id="7" data-hemx-on="click change">Delete</button><ul data-hemx-slot="todos"></ul><section data-hemx-atom="filter"></section>"#,
r#"<form class="todo-card" data-hemx-handle="create" data-hemx-form="new_todo"><input name="title" required><select name="labels" multiple><option value="urgent">Urgent</option></select><input name="__h" value="reserved"></form><button data-hemx-handle="delete" data-todo-id="7" data-hemx-on="click change">Delete</button><ul data-hemx-slot="todos"></ul>"#,
)
.unwrap();
std::fs::write(templates.join("todo.css"), ".todo-card { display: block; }").unwrap();
@@ -1141,8 +1131,6 @@ mod tests {
"pub const todo_id: ::hemx::ParamName = ::hemx::ParamName::new(\"todo_id\")"
));
assert!(generated.contains("pub mod forms"));
assert!(generated.contains("pub mod atoms"));
assert!(generated.contains("pub const filter"));
assert!(generated.contains("pub mod events"));
assert!(generated
.contains("pub const click: ::hemx::EventName = ::hemx::EventName::new(\"click\")"));
@@ -1196,10 +1184,6 @@ mod tests {
"form_field\tnew_todo\tlabels\tfalse\ttrue\n".to_owned(),
"form_field\tnew_todo\ttitle\ttrue\tfalse\n".to_owned(),
"handle_param\tdelete\ttodo_id\n".to_owned(),
format!(
"atom\ttodo.heml::filter\tfilter\t{}\n",
stable_id("atom", "todo.heml::filter")
),
"class\ttodo.css::todo-card\ttodo_card\ttodo-card\n".to_owned(),
"class\ttodo.heml::todo-card\ttodo_card\ttodo-card\n".to_owned(),
"event\ttodo.heml::change\tchange\tchange\n".to_owned(),
@@ -1611,8 +1595,6 @@ mod hemx {{
impl<K, T> KeyedSlot<K, T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} pub const fn id(self) -> ResourceId {{ ResourceId }} pub fn append_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn prepend_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn replace_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn remove(self, _: K) -> Effect {{ Effect }} pub fn move_before(self, _: K, _: K) -> Effect {{ Effect }} pub fn move_to_end(self, _: K) -> Effect {{ Effect }} }}
#[derive(Clone, Copy)] pub struct Handle<T>(::std::marker::PhantomData<T>);
impl<T> Handle<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct Atom<T>(::std::marker::PhantomData<T>);
impl<T> Atom<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct Form<T>(::std::marker::PhantomData<T>);
impl<T> Form<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct CssClass(&'static str);
@@ -1891,12 +1873,6 @@ fn main() {{
"data-hemx-handle=\"delete\"",
"ui::delete",
),
(
"atom",
r#"<template h-for="todo in &self.todos"><span data-hemx-atom="selected">Selected</span></template>"#,
"data-hemx-atom=\"selected\"",
"ui::selected",
),
] {
let base = test_dir(&format!("hemx-build-unkeyed-for-{case}-test"));
let templates = base.join("templates");
@@ -1933,7 +1909,6 @@ fn main() {{
<li data-hemx-slot="todo_row">
<template h-for="child in &todo.children" h-key="child.id">
<button data-hemx-handle="delete">Delete</button>
<span data-hemx-atom="selected">Selected</span>
</template>
</li>
</template>
@@ -1948,7 +1923,6 @@ fn main() {{
assert!(syms.contains("slot\ttodo.heml::todos\ttodos\t"));
assert!(syms.contains("slot\ttodo.heml::todo_row\ttodo_row\t"));
assert!(syms.contains("handle\ttodo.heml::delete\tdelete\t"));
assert!(syms.contains("atom\ttodo.heml::selected\tselected\t"));
assert!(syms.contains("slot\ttodo.heml::summary\tsummary\t"));
let generated = std::fs::read_to_string(out.join("hemx.generated.rs")).unwrap();
assert!(generated.contains("pub const todo_row: ::hemx::advanced::KeyedSlot"));
@@ -2394,8 +2368,6 @@ mod hemx {{
impl<K, T> KeyedSlot<K, T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} pub const fn id(self) -> ResourceId {{ ResourceId }} pub fn append_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn prepend_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn replace_html(self, _: K, _: impl ::std::convert::Into<SafeHtml>) -> Effect {{ Effect }} pub fn remove(self, _: K) -> Effect {{ Effect }} pub fn move_before(self, _: K, _: K) -> Effect {{ Effect }} pub fn move_to_end(self, _: K) -> Effect {{ Effect }} }}
#[derive(Clone, Copy)] pub struct Handle<T>(::std::marker::PhantomData<T>);
impl<T> Handle<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct Atom<T>(::std::marker::PhantomData<T>);
impl<T> Atom<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct Form<T>(::std::marker::PhantomData<T>);
impl<T> Form<T> {{ pub const fn new(_: u32) -> Self {{ Self(::std::marker::PhantomData) }} }}
#[derive(Clone, Copy)] pub struct ComponentRef(&'static str);