Impl problems that I am having

Hi guys, I kinda ran into a bit of a problem with impl.

So I created this piece of code:

struct DirPaths
{
    userprofile             : PathBuf,
    dir_config_path         : PathBuf,
    file_config             : Path,
}
impl DirPaths
{
    // Initializes
    fn init(&self) -> Self
    {
        Self
        {
            userprofile:
            {
                let userprofile = Command::new("cmd.exe")
                .arg("/c")
                .arg("echo")
                .arg("%userprofile%")
                .output()
                .expect("Failed to execute command!");
            
                let mut userprofile = String::from_utf8_lossy(&userprofile.stdout).to_string();
                
                // Removes the enter and the carriage return characters
                for _ in 0..2
                {
                    userprofile.pop();
                }
                PathBuf::from(userprofile)
            },
            
            dir_config_path:
            {
                let mut dir_config_path = PathBuf::from(self.userprofile);
                dir_config_path.push(r"Important");
                PathBuf::from(dir_config_path)
            },

            file_config: Path::new("startup_configuration.txt"),
        }
    }
}

and then I get this error message:

warning: unused import: `fs_extra::error::*`
  --> src\main.rs:11:5
   |
11 | use fs_extra::error::*;
   |     ^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
  --> src\main.rs:29:23
   |
29 |     fn init(&self) -> Self
   |                       ^^^^ doesn't have a size known at compile-time
   |
   = help: within `DirPaths`, the trait `Sized` is not implemented for `[u8]`
   = note: required because it appears within the type `DirPaths`
   = note: the return type of a function must have a statically known size

error[E0308]: mismatched types
  --> src\main.rs:59:26
   |
59 |             file_config: Path::new("startup_configuration.txt"),
   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::path::Path`, found `&std::path::Path`

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
  --> src\main.rs:31:9
   |
31 | /         Self
32 | |         {
33 | |             userprofile:
34 | |             {
...  |
59 | |             file_config: Path::new("startup_configuration.txt"),
60 | |         }
   | |_________^ doesn't have a size known at compile-time
   |
   = help: within `DirPaths`, the trait `Sized` is not implemented for `[u8]`
   = note: required because it appears within the type `DirPaths`
   = note: structs must have a statically known size to be initialized

error: aborting due to 3 previous errors; 1 warning emitted

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `learning`

To learn more, run the command again with --verbose.

I am pretty lost, do you guys happen to know how I can fix this and why this is even happening?

Turns out if I replace Path with PathBuf and I change self.userprofile to self.userprofile.display().to_string() then that fixes everything.

But I am a little confused as to why I need to change Path to PathBuf? Its got to do with a reference or something but still a little confused here?

A Path is to a PathBuf like a str is to a String. You also can't put a bare str in a struct.

How come structs restricts bare str?

Path is unsized in the same way as str and [T]. Since it's the last field of DirPath, DirPath is aso unsized. This means you can't easily create DirPath (requires using unsafe). In general avoid putting unsized types in your own. In this case swapping Path to PathBuf should put you on the right path (pun intended).

2 Likes

You should probably use something like directories::UserDirs::home_dir rather than running a command and parsing stdout. Running two additional processes to get some basic info from the OS is kind of silly.

1 Like

I think echo %whatever% should be equivalent to std::env::var("whatever") in Rust.

That does seem to be how the directories are ultimately found within the directories crate.

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.