1 00:00:00,320 --> 00:00:03,050 In this video, I'll talk about the many 2 00:00:03,050 --> 00:00:05,870 faces of Cargo. In other words, I'll give 3 00:00:05,870 --> 00:00:07,900 you a rundown of Cargos functionality. 4 00:00:07,900 --> 00:00:10,700 Cargo is a fantastic tool that comes 5 00:00:10,700 --> 00:00:13,250 with Rust. Cargo is a package manager, 6 00:00:13,250 --> 00:00:15,950 weight a package manager for a viable 7 00:00:15,950 --> 00:00:18,970 systems programming language? Yes finally, 8 00:00:18,970 --> 00:00:21,020 systems programmers can have nice things 9 00:00:21,020 --> 00:00:24,680 too. You can use Cargo to install and 10 00:00:24,680 --> 00:00:26,710 manage packages that you want to use, 11 00:00:26,710 --> 00:00:29,810 Cargo is also the build system, no more 12 00:00:29,810 --> 00:00:32,420 make files, Cargo is also the test Runner, 13 00:00:32,420 --> 00:00:35,840 and the documentation generator, etc. 14 00:00:35,840 --> 00:00:39,020 Cargo is like all the good parts of npm 15 00:00:39,020 --> 00:00:42,140 and pip and bundler and make. Let's go to 16 00:00:42,140 --> 00:00:44,600 the terminal and see Cargo in action to 17 00:00:44,600 --> 00:00:46,820 see the help output for common Cargo sub 18 00:00:46,820 --> 00:00:50,210 commands I can simply type Cargo. The 19 00:00:50,210 --> 00:00:53,150 first command we will use is new, to 20 00:00:53,150 --> 00:00:55,520 create a new Cargo package. By default 21 00:00:55,520 --> 00:00:57,829 Cargo new will create a binary package, 22 00:00:57,829 --> 00:01:00,590 or a package where we'll have an actual 23 00:01:00,590 --> 00:01:04,159 executable that we can run. Let's create 24 00:01:04,159 --> 00:01:07,860 a project called my project. 25 00:01:07,860 --> 00:01:10,290 Cargo has some nice colorful help put 26 00:01:10,290 --> 00:01:12,390 here to let us know what it did, it 27 00:01:12,390 --> 00:01:14,970 created a binary application project 28 00:01:14,970 --> 00:01:17,550 called my project. Let's see what Cargo 29 00:01:17,550 --> 00:01:21,090 created for us. 30 00:01:21,090 --> 00:01:24,720 It created a my project directory with a 31 00:01:24,720 --> 00:01:27,360 Cargo.toml config file, a source 32 00:01:27,360 --> 00:01:30,600 subdirectory with a main.rs source 33 00:01:30,600 --> 00:01:33,509 file. Notice that Cargo uses dot toml 34 00:01:33,509 --> 00:01:35,970 for its config format, that stands for 35 00:01:35,970 --> 00:01:38,610 Tom's obvious minimal language, and it 36 00:01:38,610 --> 00:01:43,939 uses dot RS for Rust source files. 37 00:01:43,939 --> 00:01:47,610 let's take a look at Cargo.toml. 38 00:01:47,610 --> 00:01:50,750 Cargo.toml is the authoritative 39 00:01:50,750 --> 00:01:54,390 config file for our project, it has the 40 00:01:54,390 --> 00:01:56,190 name of our project right here my 41 00:01:56,190 --> 00:01:58,860 project, this determines what the name of 42 00:01:58,860 --> 00:02:00,720 our project is not the name of a 43 00:02:00,720 --> 00:02:02,340 directory, or the name of a Git 44 00:02:02,340 --> 00:02:04,490 repository, it's this setting right here. 45 00:02:04,490 --> 00:02:07,860 We also have the version number Rust 46 00:02:07,860 --> 00:02:10,289 uses semantic versioning, so you will 47 00:02:10,289 --> 00:02:12,960 always see three numbers separated by 48 00:02:12,960 --> 00:02:15,300 dots, and each of the numbers have a 49 00:02:15,300 --> 00:02:17,370 specific meaning. If you're not 50 00:02:17,370 --> 00:02:19,740 acquainted with semantic versioning I 51 00:02:19,740 --> 00:02:22,830 encourage you to go see semver.org for 52 00:02:22,830 --> 00:02:25,470 more information. Then we have the 53 00:02:25,470 --> 00:02:27,600 author's usually it's just a single 54 00:02:27,600 --> 00:02:30,240 author to start with. Cargo does a really 55 00:02:30,240 --> 00:02:33,750 good job of looking for and finding your 56 00:02:33,750 --> 00:02:36,000 name and email address in various places. 57 00:02:36,000 --> 00:02:38,730 One of the places that it looks is your 58 00:02:38,730 --> 00:02:41,370 global Git config, and then we have the 59 00:02:41,370 --> 00:02:44,700 edition so every few years Rust releases 60 00:02:44,700 --> 00:02:47,130 a set of breaking changes as at edition, 61 00:02:47,130 --> 00:02:49,320 by default the edition will be the 62 00:02:49,320 --> 00:02:51,840 latest edition. So right now while in 63 00:02:51,840 --> 00:02:54,330 writing this the latest edition is 2018, 64 00:02:54,330 --> 00:02:56,130 and then you have the dependencies 65 00:02:56,130 --> 00:02:58,769 section where you specify dependencies 66 00:02:58,769 --> 00:03:00,840 that you want Cargo to manage as a 67 00:03:00,840 --> 00:03:02,820 package manager. We will use this a 68 00:03:02,820 --> 00:03:04,860 little bit later on. Now let's go look at 69 00:03:04,860 --> 00:03:06,870 the main dot RS file in the source 70 00:03:06,870 --> 00:03:08,880 subdirectory. 71 00:03:08,880 --> 00:03:11,820 Great we've already got a hello world 72 00:03:11,820 --> 00:03:14,010 program specified for us, so we've got 73 00:03:14,010 --> 00:03:16,320 our function main and then a print line 74 00:03:16,320 --> 00:03:19,050 with hello world, so let's go use Cargo 75 00:03:19,050 --> 00:03:21,410 to run project. 76 00:03:21,410 --> 00:03:25,280 Cargo run compiles and runs your project 77 00:03:25,280 --> 00:03:26,120 in one step, 78 00:03:26,120 --> 00:03:29,590 notice the lines, compiling my project, I 79 00:03:29,590 --> 00:03:32,060 finished it, some information about it, 80 00:03:32,060 --> 00:03:34,520 and then I'm running it. Notice the 81 00:03:34,520 --> 00:03:37,970 location target debug my project, 82 00:03:37,970 --> 00:03:40,100 so when Cargo builds your project it 83 00:03:40,100 --> 00:03:42,620 puts all the build artifacts inside of 84 00:03:42,620 --> 00:03:45,530 the target subdirectory. By default it 85 00:03:45,530 --> 00:03:47,230 builds in debug mode with debug symbols, 86 00:03:47,230 --> 00:03:51,500 so if we look 87 00:03:51,500 --> 00:03:53,990 there's the actual binary. Now we could 88 00:03:53,990 --> 00:03:57,470 run Cargo run again, and you can see that 89 00:03:57,470 --> 00:03:59,450 it checked and saw that nothing had 90 00:03:59,450 --> 00:04:01,550 changed, so it skipped the compiling 91 00:04:01,550 --> 00:04:04,280 stage, and told us hey we're finished and 92 00:04:04,280 --> 00:04:07,490 it ran the project again. Now if you know 93 00:04:07,490 --> 00:04:09,500 that you don't need to recompile, you 94 00:04:09,500 --> 00:04:13,270 could also just run the binary directly. 95 00:04:13,270 --> 00:04:15,580 And then we see just the hello world 96 00:04:15,580 --> 00:04:17,829 output, without the extra Cargo output, 97 00:04:17,829 --> 00:04:19,839 sometimes that's nicer. Now you 98 00:04:19,839 --> 00:04:21,820 definitely want your version control 99 00:04:21,820 --> 00:04:23,740 software to ignore the target 100 00:04:23,740 --> 00:04:26,290 subdirectory. So put that in your dot Git 101 00:04:26,290 --> 00:04:29,620 ignore or the equivalent place if you're 102 00:04:29,620 --> 00:04:31,690 using a version control system other 103 00:04:31,690 --> 00:04:33,760 than Git. Now what if you don't want to 104 00:04:33,760 --> 00:04:36,880 compile in debug mode, we can use the - - 105 00:04:36,880 --> 00:04:39,190 release flag to compile in release mode 106 00:04:39,190 --> 00:04:41,230 instead. 107 00:04:41,230 --> 00:04:44,650 Notice this time target release is the 108 00:04:44,650 --> 00:04:47,110 location of our binary, when you run in 109 00:04:47,110 --> 00:04:49,300 release mode it doesn't have debug 110 00:04:49,300 --> 00:04:51,430 symbols and it's more optimized, it takes 111 00:04:51,430 --> 00:04:54,040 longer to compile but there should be a 112 00:04:54,040 --> 00:04:56,320 noticeable improvement in speed at least 113 00:04:56,320 --> 00:04:57,370 if you have something more substantial 114 00:04:57,370 --> 00:05:00,100 than hello world program. Now let's 115 00:05:00,100 --> 00:05:02,350 explore more features of Cargo by making 116 00:05:02,350 --> 00:05:05,950 a library project. I'm going to use - - 117 00:05:05,950 --> 00:05:10,700 Lib to create a library project. 118 00:05:10,700 --> 00:05:15,060 Let's take a look, 119 00:05:15,060 --> 00:05:17,910 really similar only instead of main dot 120 00:05:17,910 --> 00:05:21,780 RS there is Lib dot RS. Let's take a look 121 00:05:21,780 --> 00:05:24,710 at what Cargo created for us. 122 00:05:24,710 --> 00:05:27,320 On the source subdirectory and Lib dot RS 123 00:05:27,320 --> 00:05:29,540 we can see that it created some tests 124 00:05:29,540 --> 00:05:31,910 for us, but there's no library content 125 00:05:31,910 --> 00:05:35,270 yet. Let's add a function this will be a 126 00:05:35,270 --> 00:05:37,520 public function, 127 00:05:37,520 --> 00:05:41,210 we'll call it four and it will return an 128 00:05:41,210 --> 00:05:43,520 integer, 129 00:05:43,520 --> 00:05:46,620 an integer will simply be for. 130 00:05:46,620 --> 00:05:49,710 So now we have a library with one public 131 00:05:49,710 --> 00:05:51,930 function and a test that ignores it, 132 00:05:51,930 --> 00:05:54,160 let's fix the test. 133 00:05:54,160 --> 00:05:57,820 First we need to import four into the 134 00:05:57,820 --> 00:06:00,680 test module, 135 00:06:00,680 --> 00:06:03,020 next let's go ahead and use it in this 136 00:06:03,020 --> 00:06:06,240 existing test. 137 00:06:06,240 --> 00:06:09,449 So here we assert that the result of 138 00:06:09,449 --> 00:06:12,330 calling our four function is an actual 139 00:06:12,330 --> 00:06:14,610 literal four. So we expect that to 140 00:06:14,610 --> 00:06:18,450 succeed, let's go run it. 141 00:06:18,450 --> 00:06:20,490 Okay, so if we look through this output 142 00:06:20,490 --> 00:06:23,100 we compiled, it finished compelling, and 143 00:06:23,100 --> 00:06:26,460 it's running our tests, and we can see 144 00:06:26,460 --> 00:06:28,020 here our it works 145 00:06:28,020 --> 00:06:30,990 tests passed, so one passing test and 146 00:06:30,990 --> 00:06:33,930 then it runs doc tests, but we don't have 147 00:06:33,930 --> 00:06:37,170 any documentation, let alone tests inside 148 00:06:37,170 --> 00:06:38,430 of our documentation yet. 149 00:06:38,430 --> 00:06:41,490 So it says running zero of those and of 150 00:06:41,490 --> 00:06:44,400 course it passes, and we're done. So we've 151 00:06:44,400 --> 00:06:47,720 run the tests using Cargo and we can see 152 00:06:47,720 --> 00:06:50,280 documentation tests run by default. So 153 00:06:50,280 --> 00:06:53,400 let's go add some documentation, and put 154 00:06:53,400 --> 00:06:55,380 a test in there and see that run. There 155 00:06:55,380 --> 00:06:57,330 are two forms of documentation comments, 156 00:06:57,330 --> 00:07:00,930 you use the first form to document the 157 00:07:00,930 --> 00:07:01,800 enclosing 158 00:07:01,800 --> 00:07:05,370 item, so to document Lib dot RS itself we 159 00:07:05,370 --> 00:07:07,410 need to use this first form, because 160 00:07:07,410 --> 00:07:10,320 there isn't a place outside of Lib de RS 161 00:07:10,320 --> 00:07:13,800 that we can document it. Two slashes and 162 00:07:13,800 --> 00:07:16,110 an exclamation mark is the documentation 163 00:07:16,110 --> 00:07:22,190 comment for the enclosing item, 164 00:07:22,190 --> 00:07:24,500 now we have some nice library 165 00:07:24,500 --> 00:07:26,980 documentation. The next form of 166 00:07:26,980 --> 00:07:30,110 documentation comment adds documentation 167 00:07:30,110 --> 00:07:32,990 to the item that follows it, this is that 168 00:07:32,990 --> 00:07:34,970 form that you will use most often, and 169 00:07:34,970 --> 00:07:41,840 this is just three forward slashes. 170 00:07:41,840 --> 00:07:44,690 Notice that you can use markdown syntax 171 00:07:44,690 --> 00:07:54,490 in your comments, now let's add a test. 172 00:07:54,490 --> 00:08:01,140 [Silence] 173 00:08:01,140 --> 00:08:03,150 Now we can see that my documentation 174 00:08:03,150 --> 00:08:06,180 test actually ran and passed. Of course 175 00:08:06,180 --> 00:08:09,000 documentation is not just for tests, it's 176 00:08:09,000 --> 00:08:11,340 also for the documentation. So let's 177 00:08:11,340 --> 00:08:13,350 generate the documentation and take a 178 00:08:13,350 --> 00:08:16,710 look. The command is Cargo doc, by 179 00:08:16,710 --> 00:08:18,510 default Cargo doc generates 180 00:08:18,510 --> 00:08:21,150 documentation for not only your project 181 00:08:21,150 --> 00:08:23,400 but for all of your dependencies as well. 182 00:08:23,400 --> 00:08:26,850 So I usually add node EPS so it doesn't 183 00:08:26,850 --> 00:08:29,130 generate documentation for all the 184 00:08:29,130 --> 00:08:31,290 dependencies, and then I usually also add 185 00:08:31,290 --> 00:08:34,140 - - open to automatically open the 186 00:08:34,140 --> 00:08:39,330 result in a browser, it looks like this. 187 00:08:39,330 --> 00:08:41,289 Cargo generates really nice 188 00:08:41,289 --> 00:08:43,539 documentation, we can see here is my 189 00:08:43,539 --> 00:08:45,929 crate, here is our top-level 190 00:08:45,929 --> 00:08:48,580 documentation that we created, here's my 191 00:08:48,580 --> 00:08:50,740 list of functions, and here's the 192 00:08:50,740 --> 00:08:53,080 documentation for my function. If we 193 00:08:53,080 --> 00:08:55,330 drill down into the function we can see 194 00:08:55,330 --> 00:08:56,940 the rest of the documentation. I 195 00:08:56,940 --> 00:08:59,110 mentioned that Cargo is a package 196 00:08:59,110 --> 00:09:02,560 manager, let's add a dependency. 197 00:09:02,560 --> 00:09:05,260 Here in the dependency section let's add 198 00:09:05,260 --> 00:09:08,050 Rand as a dependency, so we can generate 199 00:09:08,050 --> 00:09:11,560 random numbers. 200 00:09:11,560 --> 00:09:14,720 Now let's run Cargo build, 201 00:09:14,720 --> 00:09:18,319 Cargo build always builds the entire 202 00:09:18,319 --> 00:09:21,889 dependency chain, even if like here in 203 00:09:21,889 --> 00:09:24,350 our example, we're not actually using our 204 00:09:24,350 --> 00:09:26,629 dependencies, that may change sometime in 205 00:09:26,629 --> 00:09:29,029 the future, but for now be aware that if 206 00:09:29,029 --> 00:09:30,769 you add dependencies that you're not 207 00:09:30,769 --> 00:09:33,139 using you might have a much longer build 208 00:09:33,139 --> 00:09:34,370 time for no reason. 209 00:09:34,370 --> 00:09:36,889 Speaking of build times, Cargo defaults 210 00:09:36,889 --> 00:09:38,720 to parallel builds with the same number 211 00:09:38,720 --> 00:09:41,870 of jobs as CPUs. In the next video, we 212 00:09:41,870 --> 00:09:43,850 will preview the finished project that 213 00:09:43,850 --> 00:09:48,850 we will be creating in this course.