Systems Programming in Rust, best
practices. In this video, we will discuss
the practice of creating a library and
organizing it into modules. The root of
your library is Lib dot RS, located in the
source directory. A module in your
library is defined by using some form of
mod and then the module name.
If you end that with a semicolon, then
cargo will search for a file with the
same name as the module in the same
directory as Lib dot RS. Okay, but what
about nested modules? If inside my module
we define a nested module called my sub
module, that will be found in a directory
with the same name as my module, in a
file name called my sub module RS. This
nesting pattern can be repeated over and
over to an arbitrary depth. With a
structure like this, you can bring the
items inside of Lib dot RS into scope by
using my project. You can bring the items
in my module into scope by using my
project, my module, and you can bring the
items into scope from my sub module dot
RS, by using my project my module my sub
module. This is all great but we only use
libraries from some executable binaries
somewhere, so let's also go over the two
main ways that you can create a binary.
The first way is the way that we've been
using this whole course, and that's just
to have a main dot RS in the source
directory. The name of the binary this
produces is the same as the name of your
project which is my project in this
example. The other main way to specify a
binary is to place a file inside of the
bin subdirectory of source. The name of
the executable will be taken from the
name of the file. So in this example the
binaries bar, the benefit of this
approach is that you can add as many
executables as you want. If you do this
you need to remember to specify which
binary to run on the command-line when
you do your Cargo run command. So if we
put it all together a typical project
might look like this. So let's recap, this
project has two binaries, bar
and baz, it has a library, it has a module
called my module, and it has a sub module
of my module called my sub module. We
have no use for an extra binary in this
project, and we've already made good use
of library modules, so let's go
demonstrate creating a library sub
module. The first thing we need to do is
tell our stats module we want a sub
module named timer. Next we need to go
create the directory and file for the
timer to be in. The directory is stats
because it's the same as the stats
module name and then timer dot RS, it
starts empty of course, so let's go back
over to stats and go down and grab our
timer struct definition and
implementation. So here's our data fields
and our implementation, cut those, and go
paste them into timer. Next, we need to go
do our imports so we can see these items,
so I will just auto import some of these
using the IDE, if you go up you can see
it created that for us. I think that's
all we need. Next we need to go make some
things public so that we can access them,
pretty much everything is public in here,
so timer is public, all of these fields
are public, and the function and the
method that we implement are also public.
So we'll just finish that up and save.
That should be good to go. Let's go over
here and check everything, a little bit
of red here timer itself is now in a sub
module. So let's add our use statement
for timer. If we did everything right
this should work exactly like before, so
piping our hello to Cargo,
we get a warning, okay so let's go clean
up that warning, we don't use duration
anymore in this module, so we'll just
take that out, fix the brace, and then we
can go back and try again. Let's echo
hello to Cargo run once again, no
warnings this time great, just to run our
yes just for fun, okay great
looks like everything is working
normally. In the next video, I'll show you
how to write and run tests on your code.