

File IO in Rust - bherbstman
http://blog.safaribooksonline.com/2014/01/23/file-io-rust/

======
kibwen
Rust user here, and I'm actually slightly embarrassed by those code examples
because I think that our I/O APIs are far too unpolished at the moment. It's
long been one of the weakest areas of our stdlib, and though I'm glad that
we've finished the enormously-important Runtime-agnostic abstraction mentioned
in the article, we still have to put in the legwork to make the lib nice to
use.

For example, as shown in the article, the File::open function takes a Path
type. The purpose of the Path type is for safe and platform-agnostic path
manipulation... but that's really not necessary here. Say you provide a string
containing an invalid filepath to the constructor to Path: you're gonna get a
runtime failure. This is the same failure mode that you'd get just by
providing the string to File::open directly. So ideally the open function
would allow you to provide either a Path or a string directly, without forcing
you to jump through the hoop. These are the little things that I mean when I
say that our I/O APIs haven't yet had the polish they need.

~~~
andrewflnr
Out of curiosity, does Rust have an ability to provide a C++-like implicit
conversion from string to Path, so you would only need to write the Path
function? Is that kind of thing consistent with Rust's philosophy?

~~~
kibwen
Implicit conversions aren't really part of Rust's philosophy, but writing
things once is.

At the end of the day any file-opening function is gonna be reduced to passing
a string. Currently, to open a file, we take the path that you give us and
call .to_c_str() on it, but that method also exists on strings. With Rust's
trait system, we could tell the file-opening function to become generic over
any type that implements .to_c_str(), and bam: now it works on both Paths and
strings.

In practice it might be a bit of work because I don't know if we actually have
a trait for the .to_c_str() method, or if it's currently just implemented in
an ad-hoc way on types that need it. Also if you think it would be wrong to
allow one to attempt to open a file using any type that can be transformed to
a C string, then you might want to think about having a tiny wrapper trait
with a more semantic name, like .to_path_str(), which would be generic over
.to_c_str() and simply call that method on itself. Lots of little details.

~~~
mercurial
> Also if you think it would be wrong to allow one to attempt to open a file
> using any type that can be transformed to a C string, then you might want to
> think about having a tiny wrapper trait with a more semantic name, like
> .to_path_str(), which would be generic over .to_c_str() and simply call that
> method on itself.

Certainly, and for two reasons. First off, it's weakly typed. If, say, an
integer type has a to_c_str() method, it does not mean that it should be
possible to use it in File::open(). Secondly, the reliance of File::open() on
to_c_str() is an implementation detail. At the end of the day, I can't say
that having to write File::open(Path::new("foo.txt")) instead of
File::open("foo.txt") is a huge burden. Actually, I'd even go the other way
and distinguish between absolute (AbsPath) and relative (RelPath) versions of
Path.

------
bherbstman
Here's a follow-up article by the same author on Network Communication and
Serialization in Rust: [http://blog.safaribooksonline.com/2014/01/28/network-
communi...](http://blog.safaribooksonline.com/2014/01/28/network-
communication-serialization-rust/)

