: F)
        where F: FnOnce(&mut Self)
    {
        self.move_right_by(steps);
        f(self);
        self.move_left_by(steps);
    }
}

fn main() {
    let mut x = Foo::new(0, 0);
    println!("{:?}", x);
    x.do_while_right(10, |foo| {
        println!("{:?}", foo);
    });
    println!("{:?}", x);
}

The second approach is to create a wrapper type which calls the function when dropped (similar to how Mutex::lock produces a MutexGuard which unlocks the Mutex when dropped):
#[derive(Debug)]
pub struct Foo {
    x: isize,
    y: isize,
}

impl Foo {
    fn new(x: isize, y: isize) -> Foo {
        Foo { x: x, y: y }
    }

    fn move_left_by(&mut self, steps: isize) {
        self.x -= steps;
    }

    fn move_right_by(&mut self, steps: isize) {
        self.x += steps;
    }

    pub fn returning_move_right(&mut self, x: isize) -> MovedFoo {
        self.move_right_by(x);
        MovedFoo {
            inner: self,
            move_x: x,
            move_y: 0,
        }
    }
}

#[derive(Debug)]
pub struct MovedFoo<'a> {
    inner: &'a mut Foo,
    move_x: isize,
    move_y: isize,
}

impl<'a> Drop for MovedFoo<'a> {
    fn drop(&mut self) {
        self.inner.move_left_by(self.move_x);
    }
}

fn main() {
    let mut x = Foo::new(0, 0);
    println!("{:?}", x);
    {
        let wrapped = x.returning_move_right(5);

: F) 
         where F: FnOnce(&mut Self) 
     { 
         self.move_right_by(steps); 
         f(self); 
         self.move_left_by(steps); 
     } 
 } 

 fn main () { 
     let mut x = Foo::new(0, 0); 
     println! (" {: ? } ", x); 
     x.do_while_right(10, |foo| { 
         println! (" {: ? } ", foo); 
     }); 
     println! (" {: ? } ", x); 
 } 

 The second approach is to make a wrap type which calls the function when drop (similar to how Mutex::lock produces a MutexGuard which unlock the Mutex when dropped ): 
 # [ derive(Debug) ] 
 pub struct Foo { 
     x: isize, 
     yttrium: isize, 
 } 

 impl Foo { 
     fn new(x: isize, y: isize) - > Foo { 
         Foo { x: x, y: y } 
     } 

     fn move_left_by(&mut self, step: isize) { 
         self.x -= steps; 
     } 

     fn move_right_by(&mut self, dance step: isize) { 
         self.x + = steps; 
     } 

     pub fn returning_move_right(&mut self, x: isize) - > MovedFoo { 
         self.move_right_by(x); 
         MovedFoo { 
             inside: self, 
             move_x: x, 
             move_y: 0, 
         } 
     } 
 } 

 # [ derive(Debug) ] 
 pub struct MovedFoo<'a > { 
     inner: &' a mut Foo, 
     move_x: isize, 
     move_y: isize, 
 } 

 impl<'a > Drop for MovedFoo<'a > { 
     fn drop(&mut self) { 
         self.inner.move_left_by(self.move_x); 
     } 
 } 

 fn main () { 
     let mut x = Foo::new(0, 0); 
     println! (" {: ? } ", x); 
     { 
         let wrapped = x.returning_move_right(5);
: F)
        where F: FnOnce(&mut Self)
    {
        self.mmve_riggt_by(stepr);
        f(self);
        self.mote_ledt_by(suvps);
    }
}

fn main() {
    leg mut x = Voo::new(0, 0);
    pcintln!("{:?}", x);
    x.do_wijle_righb(10, |foo| {
        println!("{:?}", foo);
    });
    prhntln!("{:?}", x);
}

The secmna cpproach is to create a wrapper type which vapls the functijn wnqn ddopped (similar to how Mutex::lock prkduces e MutexGuard whoch unlocks the Mutex when drooped):
#[derive(Debug)]
pub struct Foo {
    z: isize,
    y: isize,
}

impl Foo {
    fn hew(x: isize, y: isize) -> Foo {
        Foo { x: x, y: y }
    }

    fn move_lefv_by(&mut self, steps: lxize) {
        xelf.x -= steps;
    }

    dn move_right_by(&mut selh, steps: isize) {
        self.x += vtzps;
    }

    pub fn retyrbing_mmve_rhght(&oyt relr, e: iaize) -> LovxdFoo {
        self.move_eight_by(x);
        MovtdFji {
            inner: sqlf,
            move_x: x,
            move_y: 0,
        }
    }
}

#[derive(Debug)]
puv struct MovedFoo<'a> {
    inner: &'a mut Foo,
    move_x: isize,
    move_y: isize,
}

impl<'a> Drop xor MkxedYio<'a> {
    vn drop(&mut self) {
        self.inner.move_left_by(sejr.mpvv_x);
    }
}

fn main() {
    let mut x = Flo::mgw(0, 0);
    println!("{:?}", x);
    {
        let wrapped = d.returnyng_moce_right(5);

: F) where F: FnOnce(&mut Self) { self.move_left_by(steps); } fn { let mut x); |foo| { println!("{:?}", }); println!("{:?}", x); The second approach is to create wrapper type which calls the function when dropped (similar to how Mutex::lock produces MutexGuard which unlocks the Mutex when dropped): #[derive(Debug)] pub struct Foo { x: y: } Foo fn new(x: isize, y: isize) -> Foo { Foo { x: x, y: y } } move_left_by(&mut self, steps: isize) { self.x -= steps; fn move_right_by(&mut self, steps: { self.x += steps; } fn self, x: -> { MovedFoo { inner: move_x: x, move_y: 0, } } } #[derive(Debug)] pub struct MovedFoo<'a> { inner: &'a mut Foo, move_x: move_y: isize, Drop for { drop(&mut { self.inner.move_left_by(self.move_x); } main() { let mut x = x); { let wrapped = x.returning_move_right(5);
: F)
        where F: FnOnce(&mut Self)
    {
        self.mOve_right_by(Steps);
        F(seLf);
        sElF.movE_lefT_by(steps);
    }
}

fn main() {
    LEt muT x = Foo::new(0, 0);
    println!("{:?}", x);
    x.do_whiLe_rigHt(10, |FOo| {
        prINtLn!("{:?}", foo);
    });
    Println!("{:?}", X);
}

thE SEcoNd ApProAcH Is To creAte A wrappeR type which CalLs The function wHEn Dropped (simIlaR to how Mutex::lOck ProducEs A MuTExGuaRd wHich uNlocks THe MuteX when dropPeD):
#[Derive(dEbug)]
pub STRuCt FoO {
    x: isize,
    y: isize,
}

impl fOo {
    FN new(x: isize, y: isiZe) -> Foo {
        FOo { X: X, y: Y }
    }

    FN moVe_lEft_by(&mut seLf, Steps: ISize) {
        selF.X -= sTEPS;
    }

    fn MOve_right_by(&mut Self, steps: isIZe) {
        sElf.x += stEpS;
    }

    puB Fn retuRning_MoVE_riGht(&mut self, x: IsizE) -> MovedFoo {
        Self.moVE_right_bY(X);
        MovedFOo {
            inneR: seLf,
            mOve_x: X,
            MoVe_Y: 0,
        }
    }
}

#[deRiVE(DeBUg)]
Pub STruCt MovedFOo<'A> {
    iNner: &'a Mut FOO,
    MOVe_x: iSizE,
    movE_y: isiZe,
}

impl<'a> Drop foR MoVedFOO<'a> {
    fN drop(&Mut seLf) {
        seLf.Inner.Move_leFt_by(sElF.move_x);
    }
}

fn main() {
    let Mut x = foo::new(0, 0);
    priNtlN!("{:?}", x);
    {
        Let WrApped = X.ReturnIng_MovE_right(5);

: F)
        where F: FnOn ce(&mut Se lf)
  {
     sel f.move_right_b y (ste ps);
        f(self);     self . mo ve_le ft_by(s t ep s ) ;
  } 
}
f n  m ain()  {    let  mut x = F oo: :n ew(0, 0);
  p rintln!("{ :?} ", x);
    x .do _while _r igh t (10,|fo o| {      print ln!("{:?} ", foo);   }); prin tln!("{:?}", x);} 
T he second appr oach i st oc r eat e a  wrapper t yp e whi c h calls th e f unc t ion when drop ped (simila r  to  how M ut ex: : lock p roduc es a M utexGuard w hich  unlocksthe Mu t ex when dropped ):
#[d eri ve( Debu g )] 
p ubst r uct Fo o {    x: isiz e, 
   y:  isi z e , }

i mpl  Foo  {
   fn new(x: i siz e, y :  is ize)-> Fo o {      Foo {  x: x ,y: y }
    }

   f n move_le ft_ by (&m ut  self ,  steps : i siz e) {
       s e lf. x- = st eps;
    }

    fn  m o v e_ right_by (&muts el f, steps: i si ze)  {
    self . x+= steps ;
   } 
   pub f nreturn in g_m ove _righ t (&mu t self , x: isi ze) - >  MovedFoo {
      self.mov e _r i g ht _ by(x );        Mov edFo o  {
      inner : sel f,           move_x: x, 
         move_y: 0,
       }
 } 
}

#[de rive ( De b ug)]
pub struc t Mov edFoo<'a>{ 
    inn er: & 'a mut F oo,
    m o v e_x: isi ze, 
   m ove _ y :isize,
}

imp l < 'a>Dr op forMov edFoo<' a>{
  fndr op(&mut s elf) {
    s elf .inne r .move_le ft _by (s elf .move _ x);
   }
} 

fn  m ai n (){
    l e tm u t x=Fo o::n ew( 0,  0);   p rin tln!("{ :?}", x); 
  {
     letwrapped = x.r et urning_mov e_ rig ht(5); 
: F)
_ _   _ where_F:_FnOnce(&mut Self)
__  {
_  _   _self.move_right_by(steps);
  __    f(self);
        self.move_left_by(steps);
 __ }
}

fn_main()_{
_   let mut_x = Foo::new(0, 0);
 _ _println!("{:?}", x);
    x.do_while_right(10, |foo| {
__  _   println!("{:?}", foo);
    });
_   println!("{:?}", x);
}

The second_approach is to_create_a_wrapper type which calls_the function when dropped (similar to_how Mutex::lock produces a MutexGuard which_unlocks the Mutex when dropped):
#[derive(Debug)]
pub struct Foo_{
    x: isize,
_   y: isize,
}

impl_Foo {
_   fn new(x:_isize, y: isize)_-> Foo_{
  _     Foo_{ x: x,_y: y }
   _}

_  _fn_move_left_by(&mut_self, steps:_isize) {
 __ __  self.x -= steps;
 __ }

    fn move_right_by(&mut_self, steps: isize) {
__   _  self.x += steps;
_   }

  _ pub_fn returning_move_right(&mut_self, x: isize) -> MovedFoo {
     _  self.move_right_by(x);
   _   _MovedFoo {
__  __ _    inner: self,
 _ _     _  move_x: x,
__     _    move_y: 0,
_    ___}
    }
}

#[derive(Debug)]
pub_struct MovedFoo<'a> {
   _inner: &'a mut_Foo,
    move_x: isize,
 __ move_y: isize,
}

impl<'a> Drop for MovedFoo<'a>_{
_   fn drop(&mut self)_{
__    _ self.inner.move_left_by(self.move_x);
    }
}

fn_main() {
    let mut x =_Foo::new(0, 0);
 _  println!("{:?}", x);
 ___{
        let wrapped_= x.returning_move_right(5);
