1 00:00:06,630 --> 00:00:07,463 - As you know, 2 00:00:07,463 --> 00:00:10,050 our application does quite a lot of data handling. 3 00:00:10,050 --> 00:00:14,520 Luckily for us, Rust has an extensive date/time API. 4 00:00:14,520 --> 00:00:16,470 In many ways, it's a bit too extensive 5 00:00:16,470 --> 00:00:18,300 and it's quite complicated, 6 00:00:18,300 --> 00:00:20,100 which is why I decided to cover it 7 00:00:20,100 --> 00:00:23,160 in the examples to help you understand how to dig your way 8 00:00:23,160 --> 00:00:26,250 through all the different options that you have. 9 00:00:26,250 --> 00:00:27,810 So let's take a look. 10 00:00:27,810 --> 00:00:30,660 We're gonna take a look at NaiveDate. 11 00:00:30,660 --> 00:00:33,630 That's the structure that we've used in the application. 12 00:00:33,630 --> 00:00:35,100 It represents a calendar date 13 00:00:35,100 --> 00:00:37,470 without timezone information, okay? 14 00:00:37,470 --> 00:00:39,660 And that's perfect for us. 15 00:00:39,660 --> 00:00:42,390 I don't need timezone information in my application. 16 00:00:42,390 --> 00:00:45,210 So NaiveDate fits the bill perfectly. 17 00:00:45,210 --> 00:00:48,450 If you do need timezone information, don't use NaiveDate, 18 00:00:48,450 --> 00:00:50,749 use DateTime instead. 19 00:00:50,749 --> 00:00:52,380 DateTime is generic. 20 00:00:52,380 --> 00:00:56,040 You've gotta specify a timezone as a type parameter. 21 00:00:56,040 --> 00:00:59,340 We've seen this a few times already in the course. 22 00:00:59,340 --> 00:01:02,430 We've seen DateTime and the timezone type 23 00:01:02,430 --> 00:01:06,780 that I specified was UTC, Universal Coordinated Time. 24 00:01:06,780 --> 00:01:10,500 Okay, anyway, our application uses NaiveDate 25 00:01:10,500 --> 00:01:13,620 and like I said, we're gonna dig into the details now. 26 00:01:13,620 --> 00:01:17,070 We're gonna look in types.rs at the Visit structure. 27 00:01:17,070 --> 00:01:19,500 The Visit structure, if you remember, 28 00:01:19,500 --> 00:01:21,390 it holds the data that I read in from a file. 29 00:01:21,390 --> 00:01:22,890 It contains the start date 30 00:01:22,890 --> 00:01:24,740 and the end date and the description. 31 00:01:25,650 --> 00:01:28,380 In types.rs, there's also a structure called Record. 32 00:01:28,380 --> 00:01:29,610 We haven't seen that yet, 33 00:01:29,610 --> 00:01:32,763 so I'll explain the purpose of that as well. 34 00:01:33,840 --> 00:01:38,460 Okay, so let's go into types.rs. 35 00:01:38,460 --> 00:01:42,210 And I've got the two structures Visit, 36 00:01:42,210 --> 00:01:46,110 which has various implementations and Record, 37 00:01:46,110 --> 00:01:48,210 which we haven't really discussed much yet 38 00:01:49,080 --> 00:01:51,210 and I'll describe that a bit later. 39 00:01:51,210 --> 00:01:55,710 So first things first, NaiveDate and DateTime, in fact, 40 00:01:55,710 --> 00:01:59,280 are defined in the chrono crate. 41 00:01:59,280 --> 00:02:04,280 So in my TOML file, I had to specify the chrono crate 42 00:02:04,560 --> 00:02:05,400 to download it. 43 00:02:05,400 --> 00:02:07,200 It's not part of the standard crate. 44 00:02:07,200 --> 00:02:08,790 It's okay to use it. 45 00:02:08,790 --> 00:02:10,860 Don't feel guilty 46 00:02:10,860 --> 00:02:13,170 about using stuff outside the standard crate. 47 00:02:13,170 --> 00:02:14,280 There were lots and lots 48 00:02:14,280 --> 00:02:16,080 of additional crates that you can use. 49 00:02:16,080 --> 00:02:18,660 For example, in the next lesson, we're going to look 50 00:02:18,660 --> 00:02:22,920 at MySQL and there's a dependency called MySQL, 51 00:02:22,920 --> 00:02:24,630 another crate for MySQL access. 52 00:02:24,630 --> 00:02:26,070 So it's very common 53 00:02:26,070 --> 00:02:29,970 for you to have to specify additional dependencies here 54 00:02:29,970 --> 00:02:32,120 depending on your application requirements. 55 00:02:33,060 --> 00:02:34,953 Okay, back at the types.rs, 56 00:02:35,790 --> 00:02:38,943 the data for a Visit is quite straightforward. 57 00:02:39,930 --> 00:02:42,389 Visit just specifies the start_date, 58 00:02:42,389 --> 00:02:43,890 the end_date, and the description. 59 00:02:43,890 --> 00:02:47,640 And as we've seen already, one of these visits 60 00:02:47,640 --> 00:02:49,860 will be created when the file is read. 61 00:02:49,860 --> 00:02:52,770 When I open the file for reading in my application, 62 00:02:52,770 --> 00:02:55,230 each line basically represents a Visit. 63 00:02:55,230 --> 00:02:56,880 It has a start date 64 00:02:56,880 --> 00:03:00,840 and an end date and a string description. 65 00:03:00,840 --> 00:03:04,650 So one Visit object would basically represent one line 66 00:03:04,650 --> 00:03:05,493 from the file. 67 00:03:06,600 --> 00:03:07,830 And we've already seen 68 00:03:07,830 --> 00:03:10,710 in the file handling module FH, the code that loops 69 00:03:10,710 --> 00:03:12,933 through the file and reads each line. 70 00:03:14,340 --> 00:03:16,350 So we know how to read the string 71 00:03:16,350 --> 00:03:19,200 from the file into memory. 72 00:03:19,200 --> 00:03:21,690 What we're gonna do now is see how to convert that string 73 00:03:21,690 --> 00:03:23,550 into an actual Visit. 74 00:03:23,550 --> 00:03:26,820 So let's close that down. 75 00:03:26,820 --> 00:03:29,040 One other thing to mention while I'm passing by. 76 00:03:29,040 --> 00:03:32,130 Remember, when you're defining structure, 77 00:03:32,130 --> 00:03:34,680 if you want the structure to be accessed elsewhere, 78 00:03:34,680 --> 00:03:37,140 not just in this module but in other files as well, 79 00:03:37,140 --> 00:03:40,320 then you have to declare the structure as public 80 00:03:40,320 --> 00:03:43,620 but you don't specify the implementation as public. 81 00:03:43,620 --> 00:03:47,160 Instead, you can designate individual functions 82 00:03:47,160 --> 00:03:48,720 as being public. 83 00:03:48,720 --> 00:03:51,060 So inside my Visit implementation, 84 00:03:51,060 --> 00:03:54,540 I have two public functions. 85 00:03:54,540 --> 00:03:55,920 A function here, 86 00:03:55,920 --> 00:03:59,880 this function doesn't have a self parameter. 87 00:03:59,880 --> 00:04:01,950 So in other words, it's an associated function, 88 00:04:01,950 --> 00:04:05,040 like a static function in other languages. 89 00:04:05,040 --> 00:04:07,530 You'd call this function like so. 90 00:04:07,530 --> 00:04:11,503 Upon the Visit structure you would invoke from_string. 91 00:04:14,776 --> 00:04:15,609 Like that. 92 00:04:15,609 --> 00:04:18,180 And you'd give it a line of text read in from the file. 93 00:04:18,180 --> 00:04:22,590 Let's imagine that this is the line of text 94 00:04:22,590 --> 00:04:24,290 that's been read in from the file. 95 00:04:25,470 --> 00:04:29,283 So let's just imagine that it's something like that. 96 00:04:30,720 --> 00:04:34,770 So this is what we call when we're doing in our menu, 97 00:04:34,770 --> 00:04:37,920 we say Visit::from_string and we give it a string 98 00:04:37,920 --> 00:04:42,810 with a comma-separated start_date, end_date and description. 99 00:04:42,810 --> 00:04:44,820 And the purpose of the from_string 100 00:04:44,820 --> 00:04:47,370 is to basically create a new Visit object. 101 00:04:47,370 --> 00:04:49,290 So in your code, you could say something 102 00:04:49,290 --> 00:04:52,503 like let v, which is a Visit, 103 00:04:54,390 --> 00:04:55,983 equal the return value. 104 00:04:58,110 --> 00:05:01,080 So that's the kind of understanding of the purpose. 105 00:05:01,080 --> 00:05:04,590 You would call the Visit::from_string associated function, 106 00:05:04,590 --> 00:05:06,720 static function, give it a string 107 00:05:06,720 --> 00:05:09,090 and it gives you back, it passes the string 108 00:05:09,090 --> 00:05:11,640 as we'll see, and gives you back a Visit object. 109 00:05:11,640 --> 00:05:13,380 So this is a factory function. 110 00:05:13,380 --> 00:05:15,603 It creates a Visit object from that date. 111 00:05:16,500 --> 00:05:18,060 And this is what it does. 112 00:05:18,060 --> 00:05:21,180 It takes the incoming string, the string that comes in, 113 00:05:21,180 --> 00:05:22,880 which will be something like this. 114 00:05:23,760 --> 00:05:26,193 And it splits that string at the comma. 115 00:05:27,060 --> 00:05:30,382 When you call the split function, it returns an iterator 116 00:05:30,382 --> 00:05:32,490 and iterate is like a cursor that you can loop through. 117 00:05:32,490 --> 00:05:36,450 I could write a loop on that return value or I can just say 118 00:05:36,450 --> 00:05:39,180 just give me back a list of all the items. 119 00:05:39,180 --> 00:05:40,290 So I just say collect. 120 00:05:40,290 --> 00:05:41,580 That's a common pattern. 121 00:05:41,580 --> 00:05:42,990 We've seen that a few times. 122 00:05:42,990 --> 00:05:47,040 You get back an iterator, you could iterate in a for loop. 123 00:05:47,040 --> 00:05:48,000 Can't be bothered. 124 00:05:48,000 --> 00:05:51,270 Just collect all the items into a list for me. 125 00:05:51,270 --> 00:05:53,820 When I say list, I actually mean vector. 126 00:05:53,820 --> 00:05:57,090 So this should give me back a vector of string slices. 127 00:05:57,090 --> 00:05:58,140 That's interesting, isn't it? 128 00:05:58,140 --> 00:06:02,700 Slices, it'll give me a slice that represents this portion 129 00:06:02,700 --> 00:06:05,340 before the comma and a slice that represents here, 130 00:06:05,340 --> 00:06:07,710 I specified the comma as the separator. 131 00:06:07,710 --> 00:06:10,020 I could have had different formats obviously. 132 00:06:10,020 --> 00:06:13,140 So give me back a slice, which represents that portion 133 00:06:13,140 --> 00:06:15,390 and a slice that represents that portion 134 00:06:15,390 --> 00:06:16,980 and a slice that represents that portion. 135 00:06:16,980 --> 00:06:19,740 And I get an array of those slices. 136 00:06:19,740 --> 00:06:23,163 So tokens is an array of string slices. 137 00:06:24,450 --> 00:06:26,070 What I've been doing in my demos 138 00:06:26,070 --> 00:06:29,310 is I've been specifying data types explicitly 139 00:06:29,310 --> 00:06:32,703 so that you can see clearly what's happening. 140 00:06:33,660 --> 00:06:36,390 A Rust developer would typically not bother. 141 00:06:36,390 --> 00:06:39,090 A Rust developer would typically do that 142 00:06:39,090 --> 00:06:41,010 because the compiler knows 143 00:06:41,010 --> 00:06:44,220 that the collect function returns a vector of string slices. 144 00:06:44,220 --> 00:06:47,580 Why bother extra code? 145 00:06:47,580 --> 00:06:50,280 Well, for the purposes of clarity in my demo, 146 00:06:50,280 --> 00:06:51,630 I thought it's quite useful to do it 147 00:06:51,630 --> 00:06:53,940 but in reality, I wouldn't bother. 148 00:06:53,940 --> 00:06:55,390 Anyway, let's put it back in. 149 00:06:56,416 --> 00:06:59,730 So this vector, element zero 150 00:06:59,730 --> 00:07:02,790 in this vector will be the start date. 151 00:07:02,790 --> 00:07:05,070 So I've got a function here. 152 00:07:05,070 --> 00:07:07,380 You tell date_from_string. 153 00:07:07,380 --> 00:07:12,380 I'm gonna push that discussion to the final demo later on. 154 00:07:13,920 --> 00:07:18,920 So it will take this string here. 155 00:07:18,990 --> 00:07:22,170 Token zero, tokens is my vector of tokens. 156 00:07:22,170 --> 00:07:25,110 Token zero is the start date. 157 00:07:25,110 --> 00:07:29,310 It'll take that start date and convert it into a NaiveDate. 158 00:07:29,310 --> 00:07:31,080 So we will be discussing that function later on. 159 00:07:31,080 --> 00:07:34,560 It's quite easy, but I didn't wanna get distracted just now. 160 00:07:34,560 --> 00:07:39,090 So the Visit object that I'm gonna return, the Visit object 161 00:07:39,090 --> 00:07:42,300 that I'm going to return will have a start date, 162 00:07:42,300 --> 00:07:45,513 which is the string or the date passed from there. 163 00:07:46,530 --> 00:07:48,450 And then tokens one, 164 00:07:48,450 --> 00:07:51,003 so that'll be here, the end_date. 165 00:07:52,110 --> 00:07:53,190 So that gets converted 166 00:07:53,190 --> 00:07:56,880 into a NaiveDate object and that's the end_date. 167 00:07:56,880 --> 00:08:01,533 And then tokens two is free format text at the end. 168 00:08:02,850 --> 00:08:04,440 SoKongsberg is a city in Norway 169 00:08:04,440 --> 00:08:07,560 about an hour and a half west of Oslo. 170 00:08:07,560 --> 00:08:10,110 It's quite a nice city, quite a beautiful city. 171 00:08:10,110 --> 00:08:12,450 And anyway, basically convert that into a string. 172 00:08:12,450 --> 00:08:15,510 At the moment, it's a string slice, so convert it 173 00:08:15,510 --> 00:08:18,570 into a proper string object that I can then own. 174 00:08:18,570 --> 00:08:19,620 And that's the description. 175 00:08:19,620 --> 00:08:22,050 So this is the Visit object that's gonna be created. 176 00:08:22,050 --> 00:08:23,592 Quite a nice function. 177 00:08:23,592 --> 00:08:24,900 That's quite a lot of Python. 178 00:08:24,900 --> 00:08:26,490 Python, where did that come from? 179 00:08:26,490 --> 00:08:29,970 Quite a lot of Rust-related things going on in there. 180 00:08:29,970 --> 00:08:34,380 This is quite idiomatic in usage of Rust features. 181 00:08:34,380 --> 00:08:36,210 So I was quite pleased with that function. 182 00:08:36,210 --> 00:08:38,040 Create a Visit from a string. 183 00:08:38,040 --> 00:08:40,290 It's like a parsed string function, isn't it? 184 00:08:41,520 --> 00:08:45,153 Right, quite straightforward but useful.