on master help sign in
Expose the `Node::element` constructor

But don't have it do bump allocation of each of the pieces. By allowing pre-allocated bits, we can let folks (or proc-macros) build up `Node<'static>` subtrees of unchanging nodes.

commit08ccdbb3fc89a12e5b909152acb4f7f1149bc4fa authorNick Fitzgerald <fitzgen@gmail.com> dateMon 22 Apr 2019, 10:35 (8 years ago) parentfb227aa
4 files changed+50−29
src/builder.rs+12−3 src/lib.rs+1−1 src/node.rs+35−24 src/vdom.rs+2−1
src/builder.rs+12−3
@@ -282,13 +282,22 @@ where
282282 /// ```
283283 #[inline]
284284 pub fn finish(self) -> Node<'a> {
285+ let children: &'a Children = self.bump.alloc(self.children);
286+ let children: &'a [Node<'a>] = children.as_ref();
287+
288+ let listeners: &'a Listeners = self.bump.alloc(self.listeners);
289+ let listeners: &'a [Listener<'a>] = listeners.as_ref();
290+
291+ let attributes: &'a Attributes = self.bump.alloc(self.attributes);
292+ let attributes: &'a [Attribute<'a>] = attributes.as_ref();
293+
285294 Node::element(
286295 self.bump,
287296 self.key,
288297 self.tag_name,
289− self.listeners,
290− self.attributes,
291− self.children,
298+ listeners,
299+ attributes,
300+ children,
292301 self.namespace,
293302 )
294303 }
src/lib.rs+1−1
@@ -98,7 +98,7 @@ pub mod builder;
9898
9999// Re-export items at the top level.
100100pub use self::cached::Cached;
101−pub use self::node::{Attribute, Listener, Node};
101+pub use self::node::{Attribute, Listener, Node, NodeKey};
102102pub use self::render::{Render, RootRender};
103103pub use self::render_context::RenderContext;
104104pub use self::vdom::{Vdom, VdomWeak};
src/node.rs+35−24
@@ -68,24 +68,44 @@ pub_unstable_internal! {
6868 }
6969}
7070
71−pub_unstable_internal! {
72− /// The key for keyed children.
73− #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
74− pub(crate) struct NodeKey(pub(crate) u32);
71+/// The key for keyed children.
72+///
73+/// Keys must be unique among siblings.
74+///
75+/// If any sibling is keyed, then they all must be keyed.
76+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
77+pub struct NodeKey(pub(crate) u32);
78+
79+impl Default for NodeKey {
80+ fn default() -> NodeKey {
81+ NodeKey::NONE
82+ }
7583}
7684
7785impl NodeKey {
86+ /// The default, lack of a key.
7887 pub const NONE: NodeKey = NodeKey(u32::MAX);
7988
89+ /// Is this key `NodeKey::NONE`?
8090 #[inline]
8191 pub fn is_none(&self) -> bool {
8292 *self == Self::NONE
8393 }
8494
95+ /// Is this key not `NodeKey::NONE`?
8596 #[inline]
8697 pub fn is_some(&self) -> bool {
8798 !self.is_none()
8899 }
100+
101+ /// Create a new `NodeKey`.
102+ ///
103+ /// `key` must not be `u32::MAX`.
104+ #[inline]
105+ pub fn new(key: u32) -> Self {
106+ debug_assert_ne!(key, u32::MAX);
107+ NodeKey(key)
108+ }
89109}
90110
91111/// An event listener callback function.
@@ -162,31 +182,22 @@ impl<'a> Attribute<'a> {
162182}
163183
164184impl<'a> Node<'a> {
165− /// Construct a new Node of type element with given tag name and children
185+ /// Low-level constructor for making a new `Node` of type element with given
186+ /// parts.
187+ ///
188+ /// This is primarily intended for JSX and templating proc-macros to compile
189+ /// down into. If you are building nodes by-hand, prefer using the
190+ /// `dodrio::builder::*` APIs.
166191 #[inline]
167− pub(crate) fn element<Listeners, Attributes, Children>(
192+ pub fn element(
168193 bump: &'a Bump,
169194 key: NodeKey,
170195 tag_name: &'a str,
171− listeners: Listeners,
172− attributes: Attributes,
173− children: Children,
196+ listeners: &'a [Listener<'a>],
197+ attributes: &'a [Attribute<'a>],
198+ children: &'a [Node<'a>],
174199 namespace: Option<&'a str>,
175− ) -> Node<'a>
176− where
177− Listeners: 'a + AsRef<[Listener<'a>]>,
178− Attributes: 'a + AsRef<[Attribute<'a>]>,
179− Children: 'a + AsRef<[Node<'a>]>,
180− {
181− let children: &'a Children = bump.alloc(children);
182− let children: &'a [Node<'a>] = children.as_ref();
183−
184− let listeners: &'a Listeners = bump.alloc(listeners);
185− let listeners: &'a [Listener<'a>] = listeners.as_ref();
186−
187− let attributes: &'a Attributes = bump.alloc(attributes);
188− let attributes: &'a [Attribute<'a>] = attributes.as_ref();
189−
200+ ) -> Node<'a> {
190201 let element = bump.alloc_with(|| ElementNode {
191202 key,
192203 tag_name,
src/vdom.rs+2−1
@@ -166,7 +166,8 @@ impl Vdom {
166166
167167 // Create a dummy `<div/>` in our container.
168168 initialize_container(container);
169− let current_root = Node::element(&dom_buffers[0], NodeKey::NONE, "div", [], [], [], None);
169+ let current_root =
170+ Node::element(&dom_buffers[0], NodeKey::NONE, "div", &[], &[], &[], None);
170171 let current_root = Some(unsafe { extend_node_lifetime(current_root) });
171172
172173 let container = container.clone();