diff --git a/src/lib.rs b/src/lib.rs index 6142ca9..13ed4b3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -255,7 +255,7 @@ impl Tree { *id2 = offset_id(*id2); }); } - self.vec.extend(other_tree.vec); + self.vec.append(&mut other_tree.vec); unsafe { self.get_unchecked_mut(other_tree_root_id) } } @@ -822,6 +822,22 @@ pub mod iter; /// }; /// # } /// ``` +/// Compose trees using the `@` marker: +/// ``` +/// #[macro_use] extern crate ego_tree; +/// # fn main() { +/// let subtree = tree! { +/// "foo" => { "bar", "baz" } +/// }; +/// let new_tree = tree! { +/// "root" => { +/// "child x", +/// "child y", +/// @ subtree, +/// } +/// }; +/// # } +/// ``` #[macro_export] macro_rules! tree { (@ $n:ident { }) => { }; @@ -858,6 +874,13 @@ macro_rules! tree { } }; + // Append subtree from expression. + (@ $n:ident { @ $subtree:expr $(, $($tail:tt)*)? }) => {{ + $n.append_subtree($subtree); + $( tree!(@ $n { $($tail)* }); )? + }}; + + ($root:expr) => { $crate::Tree::new($root) }; ($root:expr => $children:tt) => { diff --git a/tests/macro.rs b/tests/macro.rs index 377fb8f..768d6f5 100644 --- a/tests/macro.rs +++ b/tests/macro.rs @@ -163,3 +163,27 @@ fn mixed() { assert_eq!(manual_tree, macro_tree); } + +#[test] +fn subtree() { + let subtree = tree! { + 'x' => { 'y' => {'z'}} + }; + let tree = tree! { + 'a' => { + 'b', + 'c' => {'d', 'e'}, + @ subtree.clone(), + 'f' => { @subtree }, + } + }; + let expected_tree = tree! { + 'a' => { + 'b', + 'c' => {'d', 'e'}, + 'x' => { 'y' => {'z'}}, + 'f' => {'x' => { 'y' => {'z'}} }, + } + }; + assert_eq!(tree, expected_tree); +}