Modeling layered tree in rust












0















I'm trying to model a structure for a UI library where there exists a ViewNode which owns a RenderNode which owns a LayoutNode. These structures should at the same time form three distinct trees. A ViewTree, a RenderTree, and a Layout tree.



Is there any way of modeling this ownership without resorting to use of Rc? I don't want to use Rc<> because the ownership is clear from my point of view, The trees should never own their children (except for ViewNode), the wrapper is the owner. Each layer should also be able to be pulled out into a library and I don't want to force users of the library to use Rc<>.



Below is what I would want to do but what doesn't work. Should I go about this in a different way perhaps?



#[derive(Debug)]
struct LayoutNode<'a> {
// .. Some fields
children: Vec<&'a LayoutNode<'a>>,
}

#[derive(Debug)]
struct RenderNode<'a> {
// .. Some fields
layout_node: LayoutNode<'a>,
children: Vec<&'a RenderNode<'a>>,
}

#[derive(Debug)]
struct ViewNode<'a> {
// .. Some fields
render_node: RenderNode<'a>,
children: Vec<ViewNode<'a>>,
}

fn make_tree<'a>() -> ViewNode<'a> {
let layout_child = LayoutNode { children: vec! };
let layout = LayoutNode { children: vec![&layout_child] };

let render_child = RenderNode { layout_node: layout_child, children: vec! };
let render = RenderNode { layout_node: layout, children: vec![&render_child] };

let view_child = ViewNode { render_node: render_child, children: vec! };
let view = ViewNode { render_node: render, children: vec![view_child] };

view
}


fn main() {
println!("{:?}", make_tree())
}









share|improve this question



























    0















    I'm trying to model a structure for a UI library where there exists a ViewNode which owns a RenderNode which owns a LayoutNode. These structures should at the same time form three distinct trees. A ViewTree, a RenderTree, and a Layout tree.



    Is there any way of modeling this ownership without resorting to use of Rc? I don't want to use Rc<> because the ownership is clear from my point of view, The trees should never own their children (except for ViewNode), the wrapper is the owner. Each layer should also be able to be pulled out into a library and I don't want to force users of the library to use Rc<>.



    Below is what I would want to do but what doesn't work. Should I go about this in a different way perhaps?



    #[derive(Debug)]
    struct LayoutNode<'a> {
    // .. Some fields
    children: Vec<&'a LayoutNode<'a>>,
    }

    #[derive(Debug)]
    struct RenderNode<'a> {
    // .. Some fields
    layout_node: LayoutNode<'a>,
    children: Vec<&'a RenderNode<'a>>,
    }

    #[derive(Debug)]
    struct ViewNode<'a> {
    // .. Some fields
    render_node: RenderNode<'a>,
    children: Vec<ViewNode<'a>>,
    }

    fn make_tree<'a>() -> ViewNode<'a> {
    let layout_child = LayoutNode { children: vec! };
    let layout = LayoutNode { children: vec![&layout_child] };

    let render_child = RenderNode { layout_node: layout_child, children: vec! };
    let render = RenderNode { layout_node: layout, children: vec![&render_child] };

    let view_child = ViewNode { render_node: render_child, children: vec! };
    let view = ViewNode { render_node: render, children: vec![view_child] };

    view
    }


    fn main() {
    println!("{:?}", make_tree())
    }









    share|improve this question

























      0












      0








      0








      I'm trying to model a structure for a UI library where there exists a ViewNode which owns a RenderNode which owns a LayoutNode. These structures should at the same time form three distinct trees. A ViewTree, a RenderTree, and a Layout tree.



      Is there any way of modeling this ownership without resorting to use of Rc? I don't want to use Rc<> because the ownership is clear from my point of view, The trees should never own their children (except for ViewNode), the wrapper is the owner. Each layer should also be able to be pulled out into a library and I don't want to force users of the library to use Rc<>.



      Below is what I would want to do but what doesn't work. Should I go about this in a different way perhaps?



      #[derive(Debug)]
      struct LayoutNode<'a> {
      // .. Some fields
      children: Vec<&'a LayoutNode<'a>>,
      }

      #[derive(Debug)]
      struct RenderNode<'a> {
      // .. Some fields
      layout_node: LayoutNode<'a>,
      children: Vec<&'a RenderNode<'a>>,
      }

      #[derive(Debug)]
      struct ViewNode<'a> {
      // .. Some fields
      render_node: RenderNode<'a>,
      children: Vec<ViewNode<'a>>,
      }

      fn make_tree<'a>() -> ViewNode<'a> {
      let layout_child = LayoutNode { children: vec! };
      let layout = LayoutNode { children: vec![&layout_child] };

      let render_child = RenderNode { layout_node: layout_child, children: vec! };
      let render = RenderNode { layout_node: layout, children: vec![&render_child] };

      let view_child = ViewNode { render_node: render_child, children: vec! };
      let view = ViewNode { render_node: render, children: vec![view_child] };

      view
      }


      fn main() {
      println!("{:?}", make_tree())
      }









      share|improve this question














      I'm trying to model a structure for a UI library where there exists a ViewNode which owns a RenderNode which owns a LayoutNode. These structures should at the same time form three distinct trees. A ViewTree, a RenderTree, and a Layout tree.



      Is there any way of modeling this ownership without resorting to use of Rc? I don't want to use Rc<> because the ownership is clear from my point of view, The trees should never own their children (except for ViewNode), the wrapper is the owner. Each layer should also be able to be pulled out into a library and I don't want to force users of the library to use Rc<>.



      Below is what I would want to do but what doesn't work. Should I go about this in a different way perhaps?



      #[derive(Debug)]
      struct LayoutNode<'a> {
      // .. Some fields
      children: Vec<&'a LayoutNode<'a>>,
      }

      #[derive(Debug)]
      struct RenderNode<'a> {
      // .. Some fields
      layout_node: LayoutNode<'a>,
      children: Vec<&'a RenderNode<'a>>,
      }

      #[derive(Debug)]
      struct ViewNode<'a> {
      // .. Some fields
      render_node: RenderNode<'a>,
      children: Vec<ViewNode<'a>>,
      }

      fn make_tree<'a>() -> ViewNode<'a> {
      let layout_child = LayoutNode { children: vec! };
      let layout = LayoutNode { children: vec![&layout_child] };

      let render_child = RenderNode { layout_node: layout_child, children: vec! };
      let render = RenderNode { layout_node: layout, children: vec![&render_child] };

      let view_child = ViewNode { render_node: render_child, children: vec! };
      let view = ViewNode { render_node: render, children: vec![view_child] };

      view
      }


      fn main() {
      println!("{:?}", make_tree())
      }






      rust






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 2 at 22:02









      Emil SjölanderEmil Sjölander

      1,12831527




      1,12831527
























          1 Answer
          1






          active

          oldest

          votes


















          1














          You can use a memory arena that uses indices instead of reference counted pointers.



          Using indextree as an example:



          pub struct NodeId {
          index: usize,
          }

          pub struct Node<T> {
          parent: Option<NodeId>,
          previous_sibling: Option<NodeId>,
          next_sibling: Option<NodeId>,
          first_child: Option<NodeId>,
          last_child: Option<NodeId>,
          removed: bool,

          /// The actual data which will be stored within the tree
          pub data: T,
          }

          pub struct Arena<T> {
          nodes: Vec<Node<T>>,
          }


          The NodeId struct is a simple integer index.



          The nodes contain references to close by nodes (parent, previous_sibling, etc..) so to make for easy traversal.



          A downside of this method is that it's very similar to manual memory management, in that you need to ensure that nodes are added/removed correctly to avoid dangling references. indextree has a lot of error checking when adding/removing nodes in the tree for this reason.



          You might also want to have a look at petgraph: While this is a Graph instead of a Tree you can use it as a tree.






          share|improve this answer
























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54013760%2fmodeling-layered-tree-in-rust%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            You can use a memory arena that uses indices instead of reference counted pointers.



            Using indextree as an example:



            pub struct NodeId {
            index: usize,
            }

            pub struct Node<T> {
            parent: Option<NodeId>,
            previous_sibling: Option<NodeId>,
            next_sibling: Option<NodeId>,
            first_child: Option<NodeId>,
            last_child: Option<NodeId>,
            removed: bool,

            /// The actual data which will be stored within the tree
            pub data: T,
            }

            pub struct Arena<T> {
            nodes: Vec<Node<T>>,
            }


            The NodeId struct is a simple integer index.



            The nodes contain references to close by nodes (parent, previous_sibling, etc..) so to make for easy traversal.



            A downside of this method is that it's very similar to manual memory management, in that you need to ensure that nodes are added/removed correctly to avoid dangling references. indextree has a lot of error checking when adding/removing nodes in the tree for this reason.



            You might also want to have a look at petgraph: While this is a Graph instead of a Tree you can use it as a tree.






            share|improve this answer




























              1














              You can use a memory arena that uses indices instead of reference counted pointers.



              Using indextree as an example:



              pub struct NodeId {
              index: usize,
              }

              pub struct Node<T> {
              parent: Option<NodeId>,
              previous_sibling: Option<NodeId>,
              next_sibling: Option<NodeId>,
              first_child: Option<NodeId>,
              last_child: Option<NodeId>,
              removed: bool,

              /// The actual data which will be stored within the tree
              pub data: T,
              }

              pub struct Arena<T> {
              nodes: Vec<Node<T>>,
              }


              The NodeId struct is a simple integer index.



              The nodes contain references to close by nodes (parent, previous_sibling, etc..) so to make for easy traversal.



              A downside of this method is that it's very similar to manual memory management, in that you need to ensure that nodes are added/removed correctly to avoid dangling references. indextree has a lot of error checking when adding/removing nodes in the tree for this reason.



              You might also want to have a look at petgraph: While this is a Graph instead of a Tree you can use it as a tree.






              share|improve this answer


























                1












                1








                1







                You can use a memory arena that uses indices instead of reference counted pointers.



                Using indextree as an example:



                pub struct NodeId {
                index: usize,
                }

                pub struct Node<T> {
                parent: Option<NodeId>,
                previous_sibling: Option<NodeId>,
                next_sibling: Option<NodeId>,
                first_child: Option<NodeId>,
                last_child: Option<NodeId>,
                removed: bool,

                /// The actual data which will be stored within the tree
                pub data: T,
                }

                pub struct Arena<T> {
                nodes: Vec<Node<T>>,
                }


                The NodeId struct is a simple integer index.



                The nodes contain references to close by nodes (parent, previous_sibling, etc..) so to make for easy traversal.



                A downside of this method is that it's very similar to manual memory management, in that you need to ensure that nodes are added/removed correctly to avoid dangling references. indextree has a lot of error checking when adding/removing nodes in the tree for this reason.



                You might also want to have a look at petgraph: While this is a Graph instead of a Tree you can use it as a tree.






                share|improve this answer













                You can use a memory arena that uses indices instead of reference counted pointers.



                Using indextree as an example:



                pub struct NodeId {
                index: usize,
                }

                pub struct Node<T> {
                parent: Option<NodeId>,
                previous_sibling: Option<NodeId>,
                next_sibling: Option<NodeId>,
                first_child: Option<NodeId>,
                last_child: Option<NodeId>,
                removed: bool,

                /// The actual data which will be stored within the tree
                pub data: T,
                }

                pub struct Arena<T> {
                nodes: Vec<Node<T>>,
                }


                The NodeId struct is a simple integer index.



                The nodes contain references to close by nodes (parent, previous_sibling, etc..) so to make for easy traversal.



                A downside of this method is that it's very similar to manual memory management, in that you need to ensure that nodes are added/removed correctly to avoid dangling references. indextree has a lot of error checking when adding/removing nodes in the tree for this reason.



                You might also want to have a look at petgraph: While this is a Graph instead of a Tree you can use it as a tree.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 2 at 22:48









                CetraCetra

                2,14211724




                2,14211724
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54013760%2fmodeling-layered-tree-in-rust%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                    Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                    A Topological Invariant for $pi_3(U(n))$