DEV Community

Adam Crockett 🌀
Adam Crockett 🌀

Posted on

Rust working with paths

My first interaction with any runtime which touched the filesystem and paths was in node.js many years ago.

I have to admire the path module in node.js for its simplicity. I had to assume that other languages wouldn't do things much differently.

This year I tried c++ (kind of love it even when it gets really really really verbose and hard to follow).

Last week I picked up Rust, I wanted c++ but with a friendly face. So far I am getting the usual wobbles, "should I give up? change language again? This is also hard, I love the speed though, I can understand some of what I'm writing..." but I stick in there, I am trying to write a simple CLI tool that does nothing more than concat an input path to a current working directory, think pwd + input_path. In node that would be trivial and I could resolve paths like this:

const userInput = argv // maybe something like this "../";
path.resolve(process.cwd(), userInput); // noice!
Enter fullscreen mode Exit fullscreen mode

But googling brings me no closer, Cargo has no crates (packages) I could understand to have similar resolve functionality.

My options
0: You help me to see Im doing something wrong.
1: So do I concede that rust is not for me.
2: Try V lang
3: Use LuaJit
4: Slow but productive Use Typescript

I am quite unsure.

Top comments (22)

Collapse
 
deciduously profile image
Ben Lovy

I think std::path provides all the methods you're looking for. Did you try anything from here and have trouble with it? PathBuf is owned, like String, and Path is a reference to a slice, like str.

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Thanks Ben, I found a join method in the Path std lib, that looks fine, but Im scratching my head, there is no resolve.

I honestly don't know a lot about Rust but I think you are trying to tell me that PathBuff can do string things. I dont even know if I can split strings and mess with them as a vec.

Collapse
 
deciduously profile image
Ben Lovy • Edited

Yep, that's exactly what I was getting at. You literally just push a Path to a PathBuf and there it is, and now it's been attached as a child directory. No need to resolve anything else.

String has a split() - that should help!

Collapse
 
deciduously profile image
Ben Lovy

Ah, sorry, you're probably specifically looking for canonicalize?

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀

Probably, word on the street (StackOverflow) is that there are issues with canonicalize (I should find out more), thanks for the push, I will go check it out.

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀

also, interesting that this is part of the fs module. As I said before, I am used to node where this would be part of the path module.

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀 • Edited

Also one last thing, what the heck is Ok(()), I keep seeing this in the docs.

Thread Thread
 
deciduously profile image
Ben Lovy • Edited

I hadn't seen any issues with it in my own usage, but there's also path_abs, an external crate which solves this problem. So, the existence of the crate says that there probably is something I don't know about! Good luck.

Thread Thread
 
deciduously profile image
Ben Lovy • Edited

That's an artifact of how rust generally handles errors - all functions return a Result<T, E>. The variants of this type are Ok(T) or Err(E). Functions that don't return a value end up with an Ok(()), signalling success and returning unit. You can only use ? in a fn that returns a Result

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀

So it looks like the airquotes problem with canonicalize is that it looks at the real FS. In a cli tool where foo/ is not a dir this would panic (that to me is a real strength!) This is substantially better than node path where it's just a string. Just need catch the error. IL share working code soon.

Collapse
 
curtisfenner profile image
Curtis Fenner

Not sure how serious you are, but "V Lang" is essentially a barely functional pile of broken promises and shouldn't be used for even toy work.

If you're interested in low-level languages that are more friendly than C++ (and that's not Rust), try D. Or, for a very young and yet unstable language, try Zig.

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

I will take a look at Zig

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Interesting, I got the impression after reading the release date ... "umm theres a very specific release date here, this language is not ready is it..."

Collapse
 
juancarlospaco profile image
Juan Carlos

Nim lang one-liner Std Lib:

import os
echo getCurrentDir() / paramStr(1)

Use:

nim c -r file.nim param
/home/juan/param

(Its 2 Lines, but import can be passed on command with --import:os, so is 1)

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Passing command line imports that's cheeting, still two lines just injected haha. I got the rust thing working thanks to Ben.

Collapse
 
juancarlospaco profile image
Juan Carlos

But you dont have to pass command line imports, you can use a file.nim.cfg:

--import:os

But it was not about Code Golf anyways.
👑

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀

Well played 😁

Collapse
 
yawaramin profile image
Yawar Amin

What have you got so far? Would help to see what code you have, so we can figure out where to go from that.

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

I don't think it really helps sharing code sometimes, you either know what I'm doing or you don't and if you do, you have done it before. Not to say that you haven't Yawer, it's just a tend to get better potential answers. I will share the working code. Ben helped me out big time.

Collapse
 
yawaramin profile image
Yawar Amin

Fair enough, on re-reading your post it seems you just need doc.rust-lang.org/std/env/fn.curre... and doc.rust-lang.org/std/path/struct.... to join together the current working directory and a string directory.

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀

Thanks that is a good lead 😁

Collapse
 
devimran profile image
Imran Shaikh

I am new to Rust from NodeJS. I was facing the same issue. This is the code example i came up with.
Image description