I don't know how to solve this borrowing issue

I've got a 'installation gauge' with an error message field and a 'list of commands'.
I need the error message to be mutable as it's used by the App struct when the program quits.
The list of commands speaks for itself and doesn't need to be mutable.

However, when I try to initialize the installation gauge, the error I get is that either one needs to be mutable?

Do I need to make the list of commands mutable just so the error message field in the app object can work?

Splitting borrows doesn't work across method calls, I'm afraid. You can work around this by first deconstructing your App instance and pass drive to the method, instead of the whole App. Playground.

3 Likes

Alternatively, you can change the definition of your CommandList to not borrow drive:

-struct CommandList<'a> {
-    drive: &'a Path, 
+struct CommandList {
+    drive: PathBuf, 
     boot_partition: PathBuf,
     root_partition: PathBuf
 }

-impl CommandList<'_> {
-    pub fn new<'a>(drive: &'a Path) -> CommandList<'a> {
+impl CommandList {
+    pub fn new(drive: &Path) -> CommandList {
         CommandList {
-            drive,
+            drive: drive.into(),
             boot_partition: PathBuf::from(&format!("{}1", drive.display())),
             root_partition: PathBuf::from(&format!("{}2", drive.display()))
         }
     }

(+ a few other minor fixups)

6 Likes

This is the approach I would recommend as well.

View structs¹ in general have a very specialized (and thus limited) role to play in Rust, and unless one knows the implications and limitations, it's best to steer clear of them in order to protect one's own sanity.

¹For the purposes of this discussion, any struct with a field that is of some sort of borrow type &T

2 Likes

I went for this solution.
Parameters for initialization unowned, fields owned.
That seems to do the trick.

As an aside, it's often better to take a PathBuf parameter in a constructor than to take an &Path parameter and promptly copy it into a PathBuf. If the caller only has an &Path, then there's no change - they have to do the copy - but if they have an owned PathBuf already, and your constructor is the last thing to need it, they can move it into you, omitting the copy completely.

6 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.