- Applications can receive command line arguments,
not breaking news.
For example, when we run our application,
our application can optionally receive an argument
specifying the name of the data file to read.
If you run the application like this,
it'll actually pass in two arguments into the application.
The first argument, argument zero,
will be the name of the application
and that might be useful.
Imagine you've got some kind of error.
You might wanna display the name of the application
to the user.
And arg1 is the actual real parameter of interest
which in this case would be data.text.
Okay, so we've got some code in the util module
which grabs the command line from the user.
Our application is actually a bit more resilient
and most applications are
if the user doesn't specify this extra argument,
then it'll default to data.text anyway.
So let's see how that works.
Let's see how our application actually processes
the command line arguments.
We start off looking at util.rs,
the function parse_command_line,
and then we'll see where it's called from in main
and see what it does with the input.
Right, so in util.rs,
here's the function to parse the command lane.
So first thing I'd note is that it returns an option.
Okay, I'm looking for the name of the file
to read in, like data.text.
If the user doesn't specify that parameter,
then this function returns none to say not specified.
Otherwise, it'll return some
and it'll be the name of the file
that the user passed in.
Right, so to read command line arguments,
in the standard crate,
there's a module called env
and the env crate contains lots of useful functions
for getting information about the ambient environment
in which your application is executing.
So for example, you can in instead of env,
there's an args function,
and the args function, it gives you back
the command line arguments including argument zero
which is the name of the application,
and then argument one what we're looking for
which would be the name of the file to read in.
So it's actually worthwhile
just taking a quick look at std:env
to see what environmental information
is actually available in there.
So I've opened up the Rust documentation
for the env module in the standard crate.
And if you look at the functions defined in this module,
you'll find interesting, there's an args function,
which will give you the arguments
the programmers started with from the command line.
Okay, there are other functions as well.
You can figure out what was the directory
from which my application was executed.
The current_dir function, it's quite useful.
You can also get vars,
vars here gives you the environment variables.
So an application runs on an operating system,
in that operating system,
environment variables will be defined.
So you can pluck out environment variables from here.
Okay, so lots of useful functions.
It's the args function
that we're particularly interested in.
And the args function, when you call the args function,
it returns a structure type called args.
Okay, now it turns out that args is more like an iterator
over the command line arguments
rather than the collection of arguments themselves.
So typically what you would do is you would then iterate
over this object and grab element zero,
element one, element two, element three.
An alternative approach is to say give me all the items
that this iterator could iterate over.
Just give me the values as a list.
So the args object has a collect function
which turns out to be quite useful.
And that's what I've used here.
When I call args,
it'll give me back an iterator like a pointer.
Here's argument zero, here's argument one.
I can say I can't be bothered to iterate.
Just collect all the items together
into a list or rather a vector.
So this'll give you back a vector of command line arguments.
Argument zero is the program name
and argument one hopefully would be the filename to process.
So we get that data back into a vector of string
and then we see whether the user
actually did specify a filename at all.
If the args length is two,
then the user specified argument zero, name of program,
argument one, filename.
So in that case, grab argument one as a string, clone it.
Okay, think about ownership of strings here
just to be on the safe side.
And then we turn some, remember the option was indicating
whether these use a specified filename as a string.
Well, that's the value that I'm gonna put in there
like data.text or whatever filename
is specified from the command line.
If the argument length wasn't two,
then I'm just gonna return none.
Maybe the user didn't pass in the name of the file.
Maybe they passed in three arguments or four arguments,
but in any way, it's not what I was expecting.
So in that case, I'd just say none,
which is kind of like the equivalent of a null pointer
to say the user didn't pass in,
did not pass in a command line argument.
Okay, so that's my parse command line function.
It returns an option.
And I call that at the start of main.
So let's take a look at main, when the application starts,
from my util module we just looked at,
the parse command line function that returns an option
and which could be either some filename or none.
So a common approach when you get back an option is to say
give me the value and if it isn't the value,
then use this as a default.
That's the unwrap_or function.
We looked at that, oh, way back in lesson five
or something that seems like a lifetime ago.
So if the user did pass in a filename,
then it would give me it back.
And if the user didn't specify a filename,
then the option would be none.
When I try to unwrap it, it'll kind of fail
and it'll give me back this string as a default.
So that's basically the default filename
that the user's going to specify.
Okay, and then from there, obviously at that point,
we're then into file handling
to read the data from that file.
So if ever you want to do command line arguments,
basically you can take this code
and it's gonna look pretty much like this every time.
It's quite idiomatic. Okay, so there you go.