pr0logas
pr0logas

Reputation: 693

how to return current working directory from function?

has experience with high level programming languages. I read the Rust book and now trying to survive and understand how the "things" in Rust works. I would love that someone explain what the heck is - Ok(()) and how to deal with it? My goal is to return result from function in to the variable where the output:

    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/rcp ./file/ aba`
Ok(
    "/home/tomand/rcp",
)

Here is the full code:

use std::fs;
use std::env;
use serde_json;
use regex::Regex;
use std::path::Path;

fn determinate_file_size(file: &str) -> u64 {
    fs::metadata(file).unwrap().len()
}

fn determinate_is_it_file_or_dirctory(arg: &str) -> &str {
    let file = "File";
    let dir = "Directory";
    let re = Regex::new(r"/").unwrap();
    if re.is_match(arg) {
        return dir;
    }
    return file;
}

fn collect_user_arguments() -> Vec<String> {
    env::args().collect()
}

fn check_if_arguments_count_valid(args: &Vec<String>) -> bool {
    if args.len() == 3 {
        return true
    }
    help();
    return false
}

fn get_current_working_dir() -> Result<T> {
    env::current_dir()
}

fn help() {
    println!("Examples:");
    println!("rcp [srcfile] [destfile]");
    println!("rcp [srcdir]/[srcfile] [destdir]/[destfile]");
}


fn main() {
    let WORKING_DIR = get_current_working_dir();
    let args: Vec<String> = collect_user_arguments();

    if check_if_arguments_count_valid(&args) {
        let arg1 = &args[1];
        let arg2 = &args[2];
        println!("{:#?}", determinate_is_it_file_or_dirctory(&arg1));
    }
}

Seems the compiler tried to give me some inspiration but eventually we miscommunicate in the end:

error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
   --> src/main.rs:42:33
    |
42  | fn get_current_working_dir() -> Result<T> {
    |                                 ^^^^^^ - supplied 1 generic argument
    |                                 |
    |                                 expected 2 generic arguments

EDIT: I went with this approach:

fn get_current_working_dir() -> String {
    let res = env::current_dir();
    match res {
        Ok(path) => path.into_os_string().into_string().unwrap(),
        Err(_) => "FAILED".to_string()
    }
}

It seems more practice is required to understand the Result type and how to manage it.

Upvotes: 31

Views: 37719

Answers (1)

Netwave
Netwave

Reputation: 42756

std::env::current_dir returns a std::io::Result<Pathbuf>, so you need to use that type in your wrapper method:

fn get_current_working_dir() -> std::io::Result<PathBuf> {
    env::current_dir()
}

Playground

Other nitpick:

const is not a type so let WORKING_DIR: const = get_current_working_dir(); is wrong, just let WORKING_DIR = get_current_working_dir(); is enough.

Upvotes: 46

Related Questions