Imperartive or functional? Any improvements?

⚓ Rust    📅 2026-04-09    👤 surdeus    👁️ 4      

surdeus

I have a function I implemented in the imperative style #1:

pub fn get_attachment_dir() -> PathBuf {
    PathBuf::from(match env::var("ATTACH_DIR") {
        Ok(dir) if PathBuf::from(&dir).is_dir() => dir, 
        _ => match env::current_dir() {
            Ok(dir) => dir.into_os_string().into_string().unwrap(),
            _ => ".".to_string(),
        },
    })
}

What do not I like in the code? PathBuf is created twice. So I decided to switch to the functional style #2:

pub fn get_attachment_dir() -> PathBuf {
    env::var("ATTACH_DIR")
        .map(|dir| PathBuf::from(&dir))
        .and_then(|dir| {
            if dir.is_dir() {
                Ok(dir)
            } else {
                Err(VarError::NotPresent)
            }
        })
        .or_else(|_| env::current_dir())
        .or_else(|_| Ok::<PathBuf, VarError>(PathBuf::from(".")))
        .unwrap()
}

However, I do not like the artificial error, and using unwrap at the end. How would you write the function in more elegant and concise way?

6 posts - 3 participants

Read full topic

🏷️ Rust_feed