Transient Init() Associated Function

Say, I have a struct with a constructor and an associated init() method that further initialises the struct, like so:

#[derive(Debug)]
struct Foo {}

impl Foo {
    pub fn new() -> Foo {
        Foo {}
    }
    
    pub fn init(&self) -> Foo {
        // do some initialisation
        self
    }
}

Say further, that I want to be able to construct Foos either like this (1)

    let f = Foo::new().init();

or this (2)

let f = Foo::new();
f.init();

The above definition of init() does not compile as init() takes a reference to self but returns an owned value. However, if change the declaration to take an owned value, that is to consume self, then I can no longer use it as in (2) as f will be consumed after the call to init(). If I make init() return a reference, then I can no longer use it as in (1) ( creates a temporary which is freed while still in use). How do I solve this?

You can't have both without cloning/otherwise creating a whole new Foo with every call to init() (not recommended).

You could make it fn init(self) { ... } and use f = f.init() for (2) instead.

(Side note -- I'm not sure what kind of initialization you're thinking of, but if you need to modify the existing Foo, you would need &mut self (or consume self) and not &self.)