RUST
Code read/write system file tools
So, you woke up today wanting to know how to use file input and output calls to code system tools in Rust? Then Mihalis Tsoukalos can help.
OUR EXPERT
Mihalis Tsoukalos is a systems engineer and a technical writer. You can reach him at @mactsouk.
QUIK TIP
A Rust trait is a collection of methods defined for an unknown type: Self. Put simply, a trait describes an abstract interface that can be implemented by other data types. So traits define a behaviour. See https://doc. rust-lang.org/ std/io/trait. Read.html.
The subject of this tutorial is file input and output (I/O) in Rust. File I/O is an important part of every operating system. An OS or even a database system wouldn’t be able to function without being able to process, read, write and append to files. Apart from file I/O, in this tutorial we’re going to learn about error handling in Rust and the handy vector data type. In Rust, proper error handling is directly connected to pattern matching as well as the Result and Option data types, which we’ll also touch upon.
File descriptors
A UNIX file descriptor is a positive integer value. UNIX supports three special and standard filenames: /dev/ stdin, /dev/stdout and /dev/stderr. These can also be accessed using file descriptors 0, 1 and 2, respectively. In addition, file descriptor 0 can be accessed using /dev/fd/0 – remember that in UNIX and in Linux everything is a file. Later in this tutorial, we’re going to discuss the use of stdin, stdout and stderr in Rust. Now that we know about file descriptors, let’s crack on with pattern matching in Rust.
Pattern Matching
Pattern matching can be handy, but should be used with caution because it can create bugs and unforeseen side-effects. In Rust we use the match keyword for pattern-matching operations. A match statement should catch all possible values of the used variable, so having a default branch at the end of the block is common practice. The default branch is defined with the help of the underscore character, which is a synonym for the “catch everything that’s not specifically matched” case. There are some rare situations where a default branch isn’t required – once such case is a condition that can be either true of false. Another such case is when we examine the finite values of an enum data type – this is illustrated in enums.rs. The logic of enums.rsis found in the following match block:
Here’s the code of
errorHandling.rs as well as its output with and without the RUST_BACKTRACE environment variable set. RUST_ BACKTRACE can obtain a more detailed output in case of an error.