Is using to_owned() the idiomatic way to update a struct in place?

Viewed 2327

I was playing around with updating a Rust struct in place using chained methods. I found a way to do this, but I was not sure if my code below was idiomatic Rust versus just a workaround.

In particular, I used .to_owned() at the end of the chained method to return the borrowed struct. The code compiles and works just fine. Here is the minimal example.

//struct.rs
#[derive(Debug, Default, Clone, PartialEq)]
pub struct ModelDataCapture {
    run: i32,
    year: i32,
}
impl ModelDataCapture {
    pub fn new() -> Self {
        ModelDataCapture::default()
    }
    pub fn set_run(&mut self, run: i32) -> &mut ModelDataCapture {
        self.run = run;
        self
    }
    pub fn set_year(&mut self, year: i32) -> &mut ModelDataCapture {
        self.year = year;
        self
    }
}

//main.rs
let data_capture = ModelDataCapture::new()
    .set_run(0)
    .set_year(1)
    .to_owned(); // <<< QUESTION

println!("here is the data capture {:?}", data_capture);

Is this the proper way to write this in-place modification of the struct? If I do not include the .to_owned() method at the end of the chain, the compile fails with a message that the temporary variable does not live long enough.

2 Answers

You could change the function to take ownership over self and return self. Because each "setter" method returns the ownership of self, this code should work out nicely. For more information, please checkout the rust book

//struct.rs
#[derive(Debug, Default, Clone, PartialEq)]
pub struct ModelDataCapture {
    run: i32,
    year: i32,
}
impl ModelDataCapture {
    pub fn new() -> Self {
        ModelDataCapture::default()
    }
    pub fn set_run(mut self, run: i32) -> ModelDataCapture {
        self.run = run;
        self
    }
    pub fn set_year(mut self, year: i32) -> ModelDataCapture {
        self.year = year;
        self
    }
}

fn main() {
    //main.rs
    let data_capture = ModelDataCapture::new().set_run(0).set_year(1);

    println!("here is the data capture {:?}", data_capture);
}
Related