rust


How do I access files in a directory in Rust?


I've written a pretty straight-forward script based on the Rust docs:
use std::fs::{self, DirEntry};
use std::path::Path;
fn main() {
let path = Path::new(".");
for entry in fs::read_dir(path)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
println!("directory found!");
}
}
}
but I get the following compile errors about ?:
error[E0277]: the trait bound `(): std::ops::Carrier` is not satisfied
--> test.rs:6:18
|
6 | for entry in fs::read_dir(path)? {
| -------------------
| |
| the trait `std::ops::Carrier` is not implemented for `()`
| in this macro invocation
|
= note: required by `std::ops::Carrier::from_error`
error[E0277]: the trait bound `(): std::ops::Carrier` is not satisfied
--> test.rs:7:21
|
7 | let entry = entry?;
| ------
| |
| the trait `std::ops::Carrier` is not implemented for `()`
| in this macro invocation
|
= note: required by `std::ops::Carrier::from_error`
I only partially understand ? but I know the gist is that it allows you to act on a Result only if it's an Ok. The error here is that it's being used on a () rather than a Result, which is weird. I tried implementing the loop without ?:
use std::fs::{self, DirEntry};
use std::path::Path;
fn main() {
let path = Path::new(".");
for entry in fs::read_dir(path) {
println!("{}", entry.path());
}
}
But I get the error:
error: no method named `path` found for type `std::fs::ReadDir` in the current scope
--> test.rs:7:30
|
7 | println!("{}", entry.path());
| ^^^^
Which implies that instead of fs::read_dir returning ReadDir which is an iterator over DirEntry items, fs::read_dir is returning () which is somehow an iterator over ReadDir items?
I'm so confused.
It's probably worth mentioning that i'm running: rustc 1.16.0 (30cf806ef 2017-03-10)
The first error is because you cannot use try! or ? in a function returning ().
The second error is because read_dir returns a Result:
pub fn read_dir<P: AsRef<Path>>(path: P) -> Result<ReadDir>
Result implements IntoIterator, so path is actually the iterator you think you had.
Handling the errors and calling Path::display gets you what you want:
use std::fs;
use std::path::Path;
fn main() {
let path = Path::new(".");
for entry in fs::read_dir(path).expect("Unable to list") {
let entry = entry.expect("unable to get entry");
println!("{}", entry.path().display());
}
}
The ? operator and the try! macro will only work when your function returns a Result (in which the raised errors can be properly converted, of course). The main function does not return a result.
You may wish to send all of your code to a separate function and handle the error in main(), with something like this:
use std::io;
use std::fs::{self, DirEntry};
use std::path::Path;
fn main() {
run().unwrap_or_else(|e| {
println!("Something went wrong: {}", e.to_string());
});
}
fn run() -> io::Result<()> {
let path = Path::new(".");
for entry in fs::read_dir(path)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
println!("directory found!");
}
}
Ok(())
}

Related Links

How do I create an empty byte array?
How to return a struct with a generic type that implements the `Read` and `Write` traits?
Unused type parameters when binding a generic type to a trait that takes lifetime
Rust borrow checker prevents reuse after end of scope [duplicate]
Why does removing println! cause a Windows API function called through FFI to fail?
How to increase lifetime of the bindings [duplicate]
Is Rust's lexical grammar regular, context-free or context-sensitive?
How do I change where `cargo install` places binaries?
How to convert hex string to a float in Rust?
How do I include the end value in a range?
What files in a Cargo project should be in my .gitignore?
Repeating a Rust task with tokio_timer
error: failed to run custom build command for `onig_sys v61.1.0`
Can't use lazy static integer constant for the size of an array
Read reference from Option<&mut T> multiple times
Is there any way to tell Cargo to run its tests on the main thread?

Categories

HOME
spring-data
flask
webview
initialization
header
drag-and-drop
javafx-8
cocotb
port
alljoyn
phpstorm-2017.1
createjs
ex
spring-jpa
distributed-computing
global-variables
bnf
rest-assured
activeadmin
multi-upload
chronicle-queue
password-generator
tracing
hevc
ruby-daemons
math.js
django-import-export
microprocessors
fatfs
locks
dotcms
mapnik
knights-tour
counting
android-canvas
orchardcms-1.8
nsuserdefaults
fastlane
gitolite
extbase
swfupload
nomad
asihttprequest
destroy
liteide
ssi
password-hash
extjs4.1
spring.net
aurelia-fetch-client
case-when
rcharts
emf-compare
nitrousio
boost-compute
deviare
livecycle
nunit-console
traversable
apache-pig-grunt
processor
urbit
mnesia
gravatar
pack
arbre
opencyc
ora-04091
calcite
algebraixlib
flow-js
sql-processor
directorysearcher
zend-mail
window-resize
dmake
berkeley-db-xml
jini
neo4jphp
sensormanager
ctp
revmob
quickgraph
void-pointers
examine
xalan
arrow
voice-recording
nsfont
winsxs
fork-join
kext
fragment-identifier
hungarian-notation
solandra
chunking
explicit
.net-services
mysqli-multi-query
tacit-programming
rakudo
chronic
parentid

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App