Thank you for your help. It the same as returning a copy of Inside during the last return call of the search function. I think I'll change the search function to return an id (simple to copy) and provide another function that take an id and return a copy of the component without the component sub tree in case of the component data is needed.

Philippe


Le 27/04/2014 13:29, Artella Coding a écrit :
Hi Philippe,

The following modification of your code compiles. Not sure if it achieves what you want.

******************************************************************************
******************************************************************************

use std::vec::Vec;
use std::task;

pub enum UINode {
     DrawableNode(Container),
     ContainerNode(Inside),
}

struct Inside {
     layout: fn(&Inside) -> uint,
}

impl Inside {
     fn get_id(&self) -> uint {1}
}

trait Trait {}

struct ListInside   {
     tt: ~Trait: Send,
     list: Vec<~UINode>,
}

struct Container    {
     inside:~ListInside,
}

impl ListInside {
     fn match_fn<'a>(&'a self, filter: &'a |&'a UINode| -> Option<&'a
Inside>) ->Option<&'a Inside> {
         for inside in self.list.iter()    {
             match (*filter)(*inside)    {
                 Some(found) => return Some(found),
                 None => {},
             };
         }
         None
     }

     fn test_mutable<'a>(&'a mut self, id: uint, update: &'a|component:
&'a mut Inside|) {}
}

fn TestMatchBorrow()    {
     let task = task::task();
     task.spawn (proc()  {

         let mut viewList: Vec<~Container> = Vec::new();

         for ref mut container in viewList.mut_iter()  {
/*
//Original code
             //let &mut my_var = &mut *(container.inside);
             match container.inside.match_fn(&|inside: &UINode| ->
Option<&Inside> {None})   {
                 Some(inside) =>
container.inside.test_mutable(inside.get_id(), &|component: &mut Inside|
{}),
                 None => {},
             }
*/

//modified code
             let mut dotest = false;
             fn dummy(arg: &Inside) -> uint {
                 1
             }
             let mut ins: Inside = Inside {layout:dummy};
             match container.inside.match_fn(&|uinside: &UINode| ->
Option<&Inside> {None})   {
                 Some(inside) => { dotest = true; ins= *inside;}
                 None => {},
             }
             if(dotest == true){
 container.inside.test_mutable(ins.get_id(),
 &|component: &mut Inside| {});
             }

         }
     });

}

#[main]
fn main() {
     TestMatchBorrow();
}

******************************************************************************
******************************************************************************



On Sun, Apr 27, 2014 at 11:28 AM, Philippe Delrieu <[email protected] <mailto:[email protected]>> wrote:

    I try to implement a sort of zoom UI. The UI components are
    organized in a tree. To update a component in the UI I use a
    search function (match_fn() in the example) which take a closure
    as search criteria and if it returns something I use an update
    function (test_mutable) with a closure to do the update part. The
    update part only need an Id and the closure. So returning the
    found component is not mandatory. If the search function return
    only a copy of the component id it solves the borrow error but I
    would like to have the found component.

    I return a reference (Option<&'a Inside>) to avoid object copy. A
    component can have a large sub tree. If I change and return a copy
    in the search function (Option<Inside>) It works. Logic the Inside
    life time start at the Some level (as I understand).

    Perhaps you'll have a better idea to do this. I use this pattern
    (search and update function) for this reasons:
       * no multiple owned objects. All object are only owned in the tree.
       * maintain most immutability

    I put a new version of the test code nearer to my main code.


    use std::vec::Vec;
    use std::task;

    pub enum UINode {
        DrawableNode(Container),
        ContainerNode(Inside),
    }

    struct Inside {
        layout: fn(&Inside) -> uint,
    }

    impl Inside {
        fn get_id(&self) -> uint {1}
    }

    trait Trait {}

    struct ListInside   {
        tt: ~Trait: Send,
        list: Vec<~UINode>,
    }

    struct Container    {
        inside:~ListInside,
    }

    impl ListInside {
        fn match_fn<'a>(&'a self, filter: &'a |&'a UINode| ->
    Option<&'a Inside>) ->Option<&'a Inside> {
            for inside in self.list.iter()    {
                match (*filter)(*inside)    {
                    Some(found) => return Some(found),
                    None => {},
                };
            }
            None
        }

        fn test_mutable<'a>(&'a mut self, id: uint, update:
    &'a|component: &'a mut Inside|) {}
    }

    fn TestMatchBorrow()    {
        let task = task::task();
        task.spawn (proc()  {

            let mut viewList: Vec<~Container> = Vec::new();

            for ref mut container in viewList.mut_iter()    {
                //let &mut my_var = &mut *(container.inside);
                match container.inside.match_fn(&|inside: &UINode| ->
    Option<&Inside> {None})   {
                    Some(inside) =>
    container.inside.test_mutable(inside.get_id(), &|component: &mut
    Inside| {}),
                    None => {},
                }
            }
        });


    }

    #[main]
    fn main() {
        TestMatchBorrow();
    }

    _______________________________________________
    Rust-dev mailing list
    [email protected] <mailto:[email protected]>
    https://mail.mozilla.org/listinfo/rust-dev



_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to