jeanluc
jeanluc

Reputation: 1708

Returning iterator to RefCell

I can't figure out how to implement children_iter in the following code snippet:

  use std::{cell::RefCell, rc::Rc};                                                                                                                                                                          
                                                                                                                                                                                                             
  struct Node {                                                                                                                                                                                              
      children: Vec<Rc<RefCell<Node>>>,                                                                                                                                                                      
  }                                                                                                                                                                                                          
                                                                                                                                                                                                             
  struct NodeIterator {                                                                                                                                                                                      
      current: Rc<RefCell<Node>>,                                                                                                                                                                            
  }                                                                                                                                                                                                          
                                                                                                                                                                                                             
  impl NodeIterator {                                                                                                                                                                                        
      fn new(node: Rc<RefCell<Node>>) -> NodeIterator {                                                                                                                                                      
          NodeIterator { current: node }                                                                                                                                                                     
      }                                                                                                                                                                                                      
           
      /// Returns an iterator over the children of the current node wrapped in a NodeIterator                                                                                                                                                                                                  
      fn children_iter(&self) -> impl Iterator<Item = NodeIterator> {                                                                                                                                         
          self.current ‣Rc<RefCell<Node>>                                                                                                                                                                    
              .borrow() ‣Ref<Node>                                                                                                                                                                           
              .children ‣Vec<Rc<RefCell<Node>>>                                                                                                                                                              
              .iter() ‣Iter<Rc<RefCell<Node>>>                                                                                                                                                               
              .map(|n| Self::new(n.clone())) ‣&Rc<RefCell<Node>>                                                                                                                                             
      }                                                                                                                                                                                                      
  }                                                                                                                                                                                                          
              

The problem is I'm not sure what should contain the children as the returned iterator iterates. I've tried a few different things:

  1. Maybe I can tie the iterator to the lifetime of self?:
fn children_iter<'a>(&'a self) -> impl 'a + Iterator<Item=NodeIterator>

This fails because it returns data owned by the current function

  1. Maybe I can make self be consumed so that we don't have to keep any sort of reference to it?
fn children_iter(self) -> impl Iterator<Item=NodeIterator>

This fails with self.current does not live long enough

  1. I also tried cloning the Rc so that it doesn't refer to the one in self
self.current
    .clone()
    .borrow()
    ......

This fails with "creates a temporary which is freed while still in use"

Upvotes: 3

Views: 254

Answers (1)

jeanluc
jeanluc

Reputation: 1708

Figured it out:

self.current
    .borrow()
    .children()
    .clone()
    .into_iter()
    .map(|n| Self::new(n))

This way you return a cloned Vec that has been turned into an iterator

Upvotes: 1

Related Questions