1 00:00:06,837 --> 00:00:07,670 - In this lesson, 2 00:00:07,670 --> 00:00:10,020 we're going to investigate a complete Rust application 3 00:00:10,020 --> 00:00:12,180 that parses a CSV file. 4 00:00:12,180 --> 00:00:13,440 So this will give us a chance 5 00:00:13,440 --> 00:00:15,540 to consolidate the understanding 6 00:00:15,540 --> 00:00:18,330 of application structure in Rust in terms 7 00:00:18,330 --> 00:00:21,570 of how to break the application down into separate modules 8 00:00:21,570 --> 00:00:24,210 and a closer look at the syntax of Rust. 9 00:00:24,210 --> 00:00:25,890 We've already covered that in some detail 10 00:00:25,890 --> 00:00:26,730 but to see it applied 11 00:00:26,730 --> 00:00:30,000 in a larger application will will be nice. 12 00:00:30,000 --> 00:00:32,040 And also a closer look at some 13 00:00:32,040 --> 00:00:34,890 of the libraries available in Rust and some techniques. 14 00:00:34,890 --> 00:00:37,320 We've had a touch on some of these topics 15 00:00:37,320 --> 00:00:38,400 but we're gonna delve deeper 16 00:00:38,400 --> 00:00:40,443 into some particular libraries here, 17 00:00:40,443 --> 00:00:43,800 such as file handling and date handling, 18 00:00:43,800 --> 00:00:46,413 common requirements in lots of applications. 19 00:00:47,460 --> 00:00:49,770 So I'm going to just lead you 20 00:00:49,770 --> 00:00:52,020 through the application functionality. 21 00:00:52,020 --> 00:00:53,910 I'm going to run the application. 22 00:00:53,910 --> 00:00:57,960 It's in this project, lesson16_csv_parser. 23 00:00:57,960 --> 00:01:00,720 I'm just gonna show a couple of files initially. 24 00:01:00,720 --> 00:01:03,480 The application is gonna be reading data 25 00:01:03,480 --> 00:01:05,143 from a file called data.txt. 26 00:01:05,143 --> 00:01:08,640 It's a CSV file, comma-separated value. 27 00:01:08,640 --> 00:01:10,650 And I'm gonna show you the structure of the file 28 00:01:10,650 --> 00:01:13,890 so you can understand the scenario, the application 29 00:01:13,890 --> 00:01:16,710 and then I'll just show you the main code. 30 00:01:16,710 --> 00:01:19,320 It doesn't do much, it just kind of kickstarts lots 31 00:01:19,320 --> 00:01:20,550 of other parts of the application 32 00:01:20,550 --> 00:01:24,330 but it'll give you an idea of the overall shape. 33 00:01:24,330 --> 00:01:25,497 I'll run the application then 34 00:01:25,497 --> 00:01:27,750 and I'll go through the functionality 35 00:01:27,750 --> 00:01:30,390 so you can understand what it is we're going to achieve 36 00:01:30,390 --> 00:01:32,070 when we look at the code in detail 37 00:01:32,070 --> 00:01:33,960 for the rest of the lesson. 38 00:01:33,960 --> 00:01:36,690 Okay, so let's take a look at the code. 39 00:01:36,690 --> 00:01:40,440 Okay, so in the src folder, note this. 40 00:01:40,440 --> 00:01:43,560 I've got the main file, which is the entry point 41 00:01:43,560 --> 00:01:47,910 and then I've got four other modules, four other files 42 00:01:47,910 --> 00:01:51,450 to split the application functionality into chunks. 43 00:01:51,450 --> 00:01:56,450 Fh.rs contains all the file handling functionality. 44 00:01:56,910 --> 00:02:01,050 Menu.rs displays a menu of options to the user. 45 00:02:01,050 --> 00:02:03,060 You could have guessed that I suppose. 46 00:02:03,060 --> 00:02:05,730 Types.rs define some of the structures 47 00:02:05,730 --> 00:02:08,130 that I'm gonna use across the application. 48 00:02:08,130 --> 00:02:12,090 And then util.rs, I mean I've chosen these names myself. 49 00:02:12,090 --> 00:02:13,560 You can call 'em anything you like. 50 00:02:13,560 --> 00:02:18,390 Util.rs contains utility functions that are generally useful 51 00:02:18,390 --> 00:02:20,280 across the whole application 52 00:02:20,280 --> 00:02:22,560 and obviously, main is the entry point. 53 00:02:22,560 --> 00:02:25,500 So in an application that has multiple files, 54 00:02:25,500 --> 00:02:29,040 the first thing you do in main is to declare submodules. 55 00:02:29,040 --> 00:02:32,670 Remember the mod keyword declares a module 56 00:02:32,670 --> 00:02:35,520 and Rust then has to find the code for that module. 57 00:02:35,520 --> 00:02:39,810 And by default, it'll look for a file called types.rs. 58 00:02:39,810 --> 00:02:42,870 So this statement will kind of include the code 59 00:02:42,870 --> 00:02:45,990 for types.rs to define my data types 60 00:02:45,990 --> 00:02:48,270 and then I define a module for util, 61 00:02:48,270 --> 00:02:50,190 which will obviously pull in util.rs 62 00:02:50,190 --> 00:02:54,273 with my utility code and file handling and menu handling. 63 00:02:55,830 --> 00:02:57,720 Now, probably the first new note here 64 00:02:57,720 --> 00:02:59,550 is that the main function's very small. 65 00:02:59,550 --> 00:03:02,640 This is quite common in professional applications. 66 00:03:02,640 --> 00:03:04,260 The main function doesn't really do much. 67 00:03:04,260 --> 00:03:08,100 It kickstarts other functionality located elsewhere. 68 00:03:08,100 --> 00:03:10,830 So generally, our main function would be a couple of lines, 69 00:03:10,830 --> 00:03:13,080 literally something like this. 70 00:03:13,080 --> 00:03:14,880 So let me give you like a broad overview 71 00:03:14,880 --> 00:03:17,910 of the intent before we look at the detail later on. 72 00:03:17,910 --> 00:03:19,920 In my util module, 73 00:03:19,920 --> 00:03:22,620 the util module that I declared there, 74 00:03:22,620 --> 00:03:23,910 in my util module, 75 00:03:23,910 --> 00:03:27,750 there's a function, parse_command_line, 76 00:03:27,750 --> 00:03:29,520 which we'll have a look at later on. 77 00:03:29,520 --> 00:03:32,550 The idea when you run the application, optionally, 78 00:03:32,550 --> 00:03:36,840 you can run the application and you can specify cargo run 79 00:03:36,840 --> 00:03:38,070 and you can specify the name 80 00:03:38,070 --> 00:03:40,293 of the text file that you'd like to load in. 81 00:03:41,970 --> 00:03:44,640 If the user hasn't specified the text file 82 00:03:44,640 --> 00:03:48,870 on the command line, then it defaults to data.txt. 83 00:03:48,870 --> 00:03:50,220 So let's take a look at that now. 84 00:03:50,220 --> 00:03:51,723 Data.txt this here. 85 00:03:53,520 --> 00:03:56,700 Let me tell you a story about a country that decided 86 00:03:56,700 --> 00:03:59,970 to leave the European Union in 2016. 87 00:03:59,970 --> 00:04:00,930 Brexit. 88 00:04:00,930 --> 00:04:03,870 I live in the UK, and before Brexit, 89 00:04:03,870 --> 00:04:06,900 we could travel to Europe completely unimpinged, 90 00:04:06,900 --> 00:04:08,350 complete freedom of movement. 91 00:04:09,300 --> 00:04:11,580 Well, those days have gone, we've Brexited now. 92 00:04:11,580 --> 00:04:12,990 One of the consequences 93 00:04:12,990 --> 00:04:15,810 is that you can only travel to a European, 94 00:04:15,810 --> 00:04:19,620 Schengen country for a maximum of 90 days 95 00:04:19,620 --> 00:04:22,263 in any 180-day period. 96 00:04:23,100 --> 00:04:25,710 And I travel away to Europe a lot 97 00:04:25,710 --> 00:04:27,303 with my work and holiday. 98 00:04:28,410 --> 00:04:32,580 Living in the UK, Europe is our main holiday location. 99 00:04:32,580 --> 00:04:34,980 So I started to feel a bit anxious 100 00:04:34,980 --> 00:04:37,470 that I might accidentally be away 101 00:04:37,470 --> 00:04:40,500 for more than 90 days in 180-day period. 102 00:04:40,500 --> 00:04:41,910 And I'm not sure what would happen then. 103 00:04:41,910 --> 00:04:43,920 I don't know if I wanna find out. 104 00:04:43,920 --> 00:04:46,200 So I wrote myself a Rust program 105 00:04:46,200 --> 00:04:51,090 and here it is to keep track of all my visits to Europe 106 00:04:51,090 --> 00:04:54,420 so that I can keep track of how many days I've been away. 107 00:04:54,420 --> 00:04:55,890 It's a rolling thing. 108 00:04:55,890 --> 00:04:57,870 So for any day, you have to look back 109 00:04:57,870 --> 00:05:02,670 at the previous 180 days and you must not have traveled more 110 00:05:02,670 --> 00:05:04,890 than 90 in that window. 111 00:05:04,890 --> 00:05:07,410 Tomorrow, the window moves on a day, okay? 112 00:05:07,410 --> 00:05:10,710 So it's always looking back at the previous 180 days. 113 00:05:10,710 --> 00:05:13,410 So this actually, this date here, 114 00:05:13,410 --> 00:05:18,410 it was my first visit overseas after COVID lockdown. 115 00:05:18,570 --> 00:05:19,740 I was amazed to find out 116 00:05:19,740 --> 00:05:22,230 that this course was actually going ahead in person. 117 00:05:22,230 --> 00:05:23,640 I remember it so clearly. 118 00:05:23,640 --> 00:05:26,550 I was overjoyed to actually get the chance to travel again, 119 00:05:26,550 --> 00:05:27,450 like a lot of people. 120 00:05:27,450 --> 00:05:31,140 It was on the 30th of August 2021. 121 00:05:31,140 --> 00:05:35,640 And so the start date is the date when I arrived 122 00:05:35,640 --> 00:05:36,930 in the country. 123 00:05:36,930 --> 00:05:41,190 It was in Norway, and the end date is exclusive. 124 00:05:41,190 --> 00:05:46,190 So I was in Norway on the 7th of September 125 00:05:46,350 --> 00:05:48,240 but this date is the day after. 126 00:05:48,240 --> 00:05:50,190 And like a lot of things in programming, 127 00:05:50,190 --> 00:05:54,630 the lower index or the lower bound is inclusive 128 00:05:54,630 --> 00:05:56,703 and the upper bound is exclusive. 129 00:05:58,080 --> 00:06:00,390 So if you know the date 130 00:06:00,390 --> 00:06:03,120 after you came back and the date when you went, 131 00:06:03,120 --> 00:06:05,280 you can calculate how many days you were there. 132 00:06:05,280 --> 00:06:07,080 I've got a description of what I was doing as well. 133 00:06:07,080 --> 00:06:10,020 I was teaching C++ in Kongsberg. 134 00:06:10,020 --> 00:06:13,290 So each line is basically a different visit 135 00:06:13,290 --> 00:06:17,250 into the Schengen zone and it's mainly Norway. 136 00:06:17,250 --> 00:06:18,990 I do most of my work in Norway and I love Norway. 137 00:06:18,990 --> 00:06:20,460 I really do. 138 00:06:20,460 --> 00:06:24,960 But we went to a trip, a holiday to Malta in November 2021, 139 00:06:24,960 --> 00:06:26,820 which is our first holiday, 140 00:06:26,820 --> 00:06:29,640 like a holiday holiday for about two years abroad. 141 00:06:29,640 --> 00:06:30,473 And it was magical, 142 00:06:30,473 --> 00:06:32,400 even though it was starting to get a bit chilly 143 00:06:32,400 --> 00:06:35,310 in November in Malta, we went to Valletta, 144 00:06:35,310 --> 00:06:36,603 I'd really recommend it. 145 00:06:37,650 --> 00:06:40,770 So anyway, there we go. 146 00:06:40,770 --> 00:06:41,603 Various different... 147 00:06:41,603 --> 00:06:43,143 Now you know my calendar. 148 00:06:44,010 --> 00:06:47,760 Up to and including a course that's currently scheduled. 149 00:06:47,760 --> 00:06:52,350 Oh, that's my birthday, the 3rd of December in Copenhagen. 150 00:06:52,350 --> 00:06:55,623 That's another beautiful city, a city of spires. 151 00:06:56,640 --> 00:07:00,840 So that's my file, data.txt. 152 00:07:00,840 --> 00:07:05,430 And when I run the application, it looks to see if the user 153 00:07:05,430 --> 00:07:08,670 from the command line has specified a different file name. 154 00:07:08,670 --> 00:07:12,390 And if not, it'll just default to reading in data.txt. 155 00:07:12,390 --> 00:07:15,270 So that's the file name that's gonna get read in. 156 00:07:15,270 --> 00:07:17,610 And all my file handling functionality 157 00:07:17,610 --> 00:07:20,400 I've put into my Fh module. 158 00:07:20,400 --> 00:07:22,080 So in the Fh module, 159 00:07:22,080 --> 00:07:24,210 I've got a function called read_visits_from_file. 160 00:07:24,210 --> 00:07:25,320 I give it the file name, 161 00:07:25,320 --> 00:07:27,360 the file name that I specified up here 162 00:07:27,360 --> 00:07:30,630 and it'll give me back a collection of visits. 163 00:07:30,630 --> 00:07:35,100 I've got a structure called visit defined in types.rs. 164 00:07:35,100 --> 00:07:36,540 We'll have a look at that later. 165 00:07:36,540 --> 00:07:39,990 It says what date you visited, what date you came back 166 00:07:39,990 --> 00:07:41,370 and what were you doing there? 167 00:07:41,370 --> 00:07:43,530 Teaching C++ in plus plus in Kongsberg. 168 00:07:43,530 --> 00:07:47,100 So that's like a vector of visits. 169 00:07:47,100 --> 00:07:49,380 And then I displayed a menu. 170 00:07:49,380 --> 00:07:53,043 My menu module has a do_menu function. 171 00:07:53,970 --> 00:07:57,660 And you'll see how this works in the moment. 172 00:07:57,660 --> 00:08:02,220 It displays a list of options like calculate dates in visit. 173 00:08:02,220 --> 00:08:04,440 It gives you a chance to add another visit 174 00:08:04,440 --> 00:08:07,500 if you've just booked another trip or you can quit. 175 00:08:07,500 --> 00:08:10,410 In fact, the do_menu function, it loops around, 176 00:08:10,410 --> 00:08:14,283 allowing you to choose items repeatedly from the menu. 177 00:08:15,120 --> 00:08:18,360 But when you say quit, the function returns. 178 00:08:18,360 --> 00:08:20,130 And in fact, there are two different ways of quitting 179 00:08:20,130 --> 00:08:20,963 in my example. 180 00:08:20,963 --> 00:08:24,120 You can quit without saving any changes 181 00:08:24,120 --> 00:08:27,870 or you can quit asking for those changes to be saved. 182 00:08:27,870 --> 00:08:31,980 And this function, as we'll see, returns a true or false. 183 00:08:31,980 --> 00:08:35,010 If it returns true, it means the user chose 184 00:08:35,010 --> 00:08:38,040 to quit the application and save the changes they've made 185 00:08:38,040 --> 00:08:39,690 to the itinerary. 186 00:08:39,690 --> 00:08:44,430 So if this function returns true, then I save the visits 187 00:08:44,430 --> 00:08:46,200 that have been updated back to the file. 188 00:08:46,200 --> 00:08:50,940 And again, write_visits_to_file is defined in my Fh module. 189 00:08:50,940 --> 00:08:53,280 So over the next few sections, 190 00:08:53,280 --> 00:08:55,650 we're gonna delve into the file handling. 191 00:08:55,650 --> 00:08:57,510 We talk about utility handling as well 192 00:08:57,510 --> 00:09:00,000 and dates, times, and command line parsing. 193 00:09:00,000 --> 00:09:03,180 So you'll see how it all works, but you can kind 194 00:09:03,180 --> 00:09:06,150 of get a framework for what we're trying to achieve here. 195 00:09:06,150 --> 00:09:07,950 So I'm gonna run the application, I'm gonna play with it 196 00:09:07,950 --> 00:09:10,140 for a few minutes and you can as well 197 00:09:10,140 --> 00:09:12,190 just to get a flavor for what's going on.