Returning a String Property from an Object in a Getter Method

I’m working on a file interaction library which has a kind of Factory Functionality for Serializing and Deserializing String Text Data.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=310d38e4722077e001d2438ea1390b84
So I don’t want the String Data to stay in the Serializer Object which is actually kind of disposable. Rather I want the String Data to be owned by the calling Object within the rest of the Application.
But when I try to return the String Data and its Ownership with the Getter Method:

    pub fn pass_content(&mut self) -> String {
        self._scontent
    }

I get an Compiler Error:

error[E0507]: cannot move out of borrowed content
   --> src/main.rs:265:5
    |
265 |     self._scontent
    |     ^^^^^^^^^^^^^^ cannot move out of borrowed content

Then I also tried to pass the data to a local Variable so I could rebuild the Object Property with a valid String Object:

    pub fn pass_content(&mut self) -> String {
        let mut scntnt = self._scontent;
        
        
        self._scontent = String::new();
        
        scntnt
    }

But this produces an Error as well:

warning: variable does not need to be mutable
   --> src/main.rs:253:13
    |
253 |         let mut scntnt = self._scontent;
    |             ----^^^^^^
    |             |
    |             help: remove this `mut`
    |
    = note: #[warn(unused_mut)] on by default

error[E0507]: cannot move out of borrowed content
   --> src/main.rs:253:26
    |
253 |         let mut scntnt = self._scontent;
    |                          ^^^^^^^^^^^^^^
    |                          |
    |                          cannot move out of borrowed content
    |                          help: consider borrowing here: `&self._scontent`

If I borrow only a Reference to the String Data with &self._scontent the Caller Object wouldn’t obtain Ownership of the Data.

Please, are there any suggestions to get the String Data out of the Deserializer Object?

Since you don’t need the data to stay there,

pub fn take_content(&mut self) -> String {
    std::mem::replace(&mut self._scontent, String::new())
}

Or it might be better to store an Option<String> and call take():

pub fn take_content(&mut self) -> String {
    self._scontent.take()
        .expect("cannot call take_content more than once!")
}

so that it can panic if called multiple times.

1 Like

Thank you for the valuable Hint.
Actually I didn’t think yet of the Use Case of multiple Callers trying to take the same content from the Deserializer.

I needed to refacture the String Data Processing Logic a bit
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7e00971f59bfbb3eae5d9718f1710207
I also thought that a
FileDriver::take_content() Call on FileDriver._scontent == None
should not be an Error and should not be Fatal
because it simply might be that there is a Call of FileDriver::take_content() before FileDriver::read()