Crates are about code sharing between projects, while modules are about code sharing within a project.
Modules are a collection of items such as named features like structs and functions.
We can create a module using the mod keyword, but let's start off with creating our first library.
To do this, we type in cargo new like always, and then the name we want our crate to be.
And then we add tic tac lib to it to specify that we want to create a library.
So let's change into that directory and let's look what's inside the source folder, which as I mentioned
in the previous lecture, is going to be lib rs.
So we can delete all the contact contents out of here and we can declare our first module, which we
will call mod list and then open and close brackets.
And here we can create additional modules like mod things to do, mod items completed.
So now we have two modules inside of our module.
So now let's add a struct called task.
And then in here, we're going to have an item that is of type string and then let's add some functions
inside of our things to do.
So we'll say add activity,
update activity
and marked completed.
And then let's add a couple down to items completed such as remove task and move back to do.
So a useful tool that we can install is cargo modules and we can install it by running cargo and small
cargo modules.
And I already have this installed, so pause the video while you wait for yours to install, but once
it is installed you can start running a command as such cargo.
Modules generate tree.
And what this is going to do is it's going to display to us the.
Set up of our crate with the modules inside of it, but we can also make it a little better by adding
with types to it.
And now we can see our structs and our functions that are inside of our modules.
And then here you can see the pub keyword a lot.
The pub keyword makes an item public so it can be accessed from outside the module.
One function is marked pub crate and that is so that it is available anywhere inside the crate, but
it isn't exposed to anything external to the crate.
So in this case, our pub crate is our list module.
If there is no pub keyword then the item is pub self, which we can see pretty much everywhere currently.
Which pub self is equivalent to private and other languages and it is the default choice when we are
implementing a function or a struct or whatever else there might be.
So if we wanted to make it public, then simply just add the pub keyword.
So if we rerun our tree with types, we can now see that the task struck is now public and we have a
green pub word to differentiate itself from pub self, which again means private.
So let's add a function down here and see how we can access some of these functions in the struc inside
of our modules.
So let's call it let's add task and then we'll say let task equal list task.
Tags and then we'll say item string from task.
Okay, so we got a red squiggly and let's cargo build it.
That way we can see what our air is going to be.
So it is telling us that the item is a private field.
So even though we made tasks public, we have to make the fields inside of it also public.
So now if we cargo build it just to make sure the error is gone, we're now good with that.
So let's try to access some of our functions.
So we'll say list things to do, add activity.
And the first thing that we see is that things to do is private.
So put pub in front of it and then we see add activity gets it.
So we have to make that function public as well.
And the way that we did this is called the relative path because we said, hey, go to the list module
and then go to things to do and then go to add activity.
But if we want to do our absolute path, then we would start it off with the crate keyword and then
follow it the same way.
And this is the absolute path
because we start at the.
Root crate, which is designated here by this crate keyword.
But you can imagine that as a project grows, we wouldn't want just this one lib RC file to contain
every module.
That'd be a nightmare to maintain, but luckily we can export modules to different files.
So what we're going to do is we're going to first start off by exporting out the things to do module.
So inside source folder, we're going to create a new file called Things to Do.
RS And then we're going to take the functions out of here.
Go to things to do, paste them in, and then we can remove this entire block of code.
So now we need to add a couple of things we need to say mod things to do and that's going to tell rust,
hey, I want you to look for a things to do.
File.
So it's going to have to be called exactly things to do.
And now what we can do is we can come down here and remove list.
Now everything is back to the way that it was.
So it would kind of be a pain if every time we wanted to call something inside of things to do, have
to type out things to do.
So what we can actually do here, so say we want to be able to call add activity is we can say use,
create things to do and then add activity.
And now we can remove all of this.
As you can see, they are now exactly equivalent.
So now we can actually remove this one and now we're good to go.
But how about nested modules?
How can we split those into different files?
Well, let's create a new folder.
Called Things to do.
And then when we use mod things to do, rust is going to look for things to do.
Which we already created.
And then all the sub modules will appear in the things to do directory and cargo will know to look there
for sub modules as long as we add in here.
Pub mod name of module.
So let's go ahead and do that.
Let's move.
Items completed.
Into.
Things to do directory.
So inside of there let's create a new file called Items Completed RS.
And then we'll go back in here and we're going to take these.
Place it inside of here.
And then just so that we can access at least one of them, we'll make it public.
And then our name of our module is now items completed.
We can come back into here.
And we can remove this.
And we can add in.
Use things.
Okay.
Things to do.
Items completed.
And then here we can now reference items completed remove task, which is what we made public in this
case.
So and then everything else is basically the same now.
So if we wanted to, we can come inside items completed say pub mod test to create a new module called
Test add in a test function.
And then we can go back into libraries and say, use things to do items completed.
Test.
And now we can just call.
Test like normal and that's pretty much all there is to it, to modules.
It is a bit unique against other languages, but it is pretty simple once you understand how cargo likes
the structure of it to be.
And now let's just take a look at our new generate tree with types and we can see that we have our public
task struck a couple of public functions, a public module called items completed.
With a couple of more functions in it that are public as well as our other module and the function that
we just created.
So again, I think that cargo modules generate tree is a very powerful tool to help us visualize our
structure.
So hopefully it helps you out as you take your journey into figuring out modules.