Intro Guide to Rust Documentation With Rustdoc πŸ¦€ Rust Tutorial for Developers

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys my name is Trevor Sullivan and welcome back to my video channel thank you so much for joining me for yet another video in our rust programming tutorial series now in most of the past videos that we've been covering so far we've covered a lot of topics surrounding the code itself in Rust so how do we declare variables how do we declare custom data structures how do we declare enumerations how do we Implement traits and things of that nature now what we're going to be shifting topics a little bit here it's still going to be rust centered but rather than talking so much about the code in Rust we're actually going to be talking about how to document our code so that anybody who's using your application or a library that you writ wrote for rust is going to be able to look at the documentation for your project and be able to figure out how to integrate your custom Library into their own application or use your command line tool if you're publishing a binary project as opposed to a library so there's a really cool utility that's included as part of the rust tool chain and this is known as rust dock so you can actually just run rust stock at the command line once you've got the rust tool chain installed and this is the utility that's going to help to generate your documentation from your actual source code now you can also run rust stock through the cargo CLI tool and this is generally more preferable than calling rust stock directly because when you use the cargo dock command you it can actually have some of the parameters passed automatically for you so that you don't have to type out the entire rustdoc CLI command with all of the arguments to point rust stock to your specific project so as long as you've got your cargo project initialized you've got your cargo.tomel file you can just do a cargo dock command and that'll automatically kind of figure out where your project is and it'll spit out your documentation into your target folder which is typically where the binaries that are compiled for your application in debug or release mode are generated as well so instead of a debug a release folder it'll plug your documentation files into that doc folder now the nice thing about using rust dock is that this generates the same documentation that you see on websites like Doc dot RS so if we go over to doc.rs right here and we look for a library such as survey for example which I did a video on recently talking about how to serialize and deserialize Json data from rust you'll see that we have this crate level documentation this kind of introduces the purpose of this particular library and then as you kind of go down further there's a separate section that talks about the child modules that are exported by this crate so you can have a crate you can break it down into child modules and then each of those child modules within your crate can also Define things like functions and traits and data types or data structures using the struct keyword so as you kind of drill down here you'll see we have structs enums traits in these different modules and this format of this documentation is actually the exact same thing that you see when you use rust stock to generate documentation locally on your development workstation so when you run the cargo doc command and ultimately invoke the rust stock CLI it basically spits out some static HTML that structured very similar to what you see right here on docs.rs and that'll give you a nice preview of what other people are going to see when they seek out the official documentation for your project now the other cool thing to note about docs.rs here is that this is the official documentation site for crates that are published to the official rust registry I almost said container registry I was thinking more of Docker Hub but we're talking about the rust crate registry at crates dot IO so if you head out to crates.io right here and you look for something like survey or maybe you know rocket.rs or something like that then when you check out the documentation over here you'll often see a link to the docs.rs page for that particular project let me check out surday here to see if that's where there's links to yeah sure enough survey does actually link directly out to docs.rs I guess rocket just chose to self-host their own documentation and use that as the primary source but oftentimes most of the time I would even argue that you're going to see a link to docs.rs and that'll be kind of the authoritative location for the documentation for various rust crates that you come across also another library that I did a video on was the clap Library here so if we go over there once again you can see that if you want the documentation for the clap library to parse command line arguments that's going to take you directly over to to docs.rs now one of the things I really like about using docs.rs is that it shows you the historical versions right here so it actually looks at all the metadata for your cargo.tamil file and it displays all of the different historical versions so if somebody is running a specific version of your library and they need to look at documentation for that specific version they can actually just find that version list right in here plus there are external links back from docs.rs to crates dot IO the original source code for this project so if it's hosted over on GitHub it'll take you straight over to GitHub as in the case of clap right here and so it's just a really nice experience you can also do searches here and this search feature is included when you render the static HTML documents locally as well so you don't have to implement that yourself it's just an automatic out of the box feature provided by rust stock itself there's keyboard shortcuts so you can do just you know shift question mark or shift forward slash to do a question mark and that'll show the keyboard help here also if you're scrolling somewhere in the docs and you want to do a search you can just hit s on your keyboard and that'll jump you up to the search bar here and so having this standardized format for everything rust related is really nice so that you don't have to go out and seek out different types of tool chains like maybe docusaurus which is a static site generator that I actually use for one of my websites docs.opensrc.dev and so rather than having to have all of these disparate systems for documentation everything in Rust is kind of unified in this rust dock tool chain so we're going to be taking a look at how you can actually write your own documentation in your rust crates that uses this exact same structure so that you have consistency with the look and feel of the documentation for your project now I would encourage you to as you're working with rust documents or comment based documentation in your source code files I would encourage you to check out the reference here for for rust stock so if you just go out to your favorite search engine and just search for the rust doc book right here this is one of the core kind of books that's provided by the rust project and it just helps you understand all the different features that are available in Rust stock for example you can just use markdown right inside of your documentation so if we take a look at how to write docs it's going to show us you know how do you use different types of comments here at the crate level at the individual function level at the struct or enum level individual enum variants individual fields on structs can also be documented as well so there's special syntaxes that you're going to need to memorize trust me there's not too much that you have to memorize just a few key things and again I always encourage people to spend Hands-On time with these utilities so that when it comes time to actually write your documentation you're not fiddling too much with the tooling but you're able to efficiently write the documentation and then get back to enhancing your module or your crate with new new features bug fixes and so on and so forth so we're going to be taking a look at how to kind of do create level documentation and do documentation and things like the module level things at the function level at the enum level the struct level all that stuff there's also a doc attribute here that allows you to embed external markdown files if you want to so technically when you do a triple slash it's actually expanding to this doc attribute here but it actually allows you to include separate markdown files so if you don't want to use help documentation directly inside of your source code you can actually use this include string macro to 0.2 external markdown files that you can then basically bring in at document generation time and that helps to keep your source code a little bit more clean but you can still document things in these external markdown files there's also the ability to create links between different types and functions within your library you can also write inline tests so you can basically create a block of code as part of your module and just using these triple backticks right here you can say all right this block of code is actually going to test out this particular function or type and then it'll actually allow you to run cargo test commands to parse those code samples and then execute them so that you can make sure that your code is actually working the way that you expect so being able to embed your tests inside of comments is super cool as well there's also some other Advanced features but we're just going to cover some of the primary features of rust stock so without further Ado let's go ahead and spin up a scratch project we're not going to do any smoke and mirrors here I don't have anything pre-prepared I have practiced it personally but I'm not going to just kind of throw you a project that doesn't really make sense to you as far as the structure and then try to kind of explain it to you we're actually going to do everything completely from scratch so that if you're building a rust library or binary application from the ground up you'll be able to follow the same kind of series of steps right so before we actually jump into the code I just wanted to encourage you to subscribe to my channel I am in independent content creator so any kind of support that you lend to this channel helps me to bring you content like this video as well as the past videos in the rust Series so make sure that you subscribe to the channel and click on the Bell icon on so that you get notified in the YouTube application about any new videos that are published also I have this playlist featured right down here on my channel that covers the rust programming language where up to 27 published videos so far so this will be the 28th video and if there's any topics in here that you aren't familiar with feel free to just kind of go through the list of videos in this playlist and feel free to just jump into any of those topics if you want to learn about threading we've got videos on that if you want to learn about mutexes and sharing data between threads feel free to check out that video if you want to send messages between threads with channels then feel free to check out that video we've got Json parsing file system apis CLI argument parsing and a whole bunch of other stuff in here and there's a lot more to come as well because rust is a huge popular language and it's growing on a regular basis also please leave a comment down below and let me know what you thought of this video and leave a like on the video If you learned at least one thing new by the end of the video or if you just enjoyed it watching this this video for whatever reason also I'm going to leave some links down in the pinned comment down below so if you want to provide some support to this channel you can click those links and make a purchase and then that'll help to support this channel as well so I really appreciate all of the support that you guys have provided so far and my objective is really to continue bringing bringing you great content on Rust and other technical topics all right so let's go ahead and spin up a new project and because we're going to be dealing with a local web browser I'm not going to be using my remote Linux system for Development I've actually got the rust tool chain installed on my local Windows system here and so because I need to be able to open my HTML files locally after I generate them with rust dock we're just going to be using my Windows system for the time being just to keep things simple also I do have a Linux virtual machine here running Ubuntu Studio so sometimes I actually do use this system to do graphical work but the remote desktop protocol is a little bit slow and so sometimes I don't necessarily prefer to use this environment just to keep things high performance and fluid and everything but if I need to I will jump into my desktop Linux system that's running as a local hyper-v virtual machine all right so on my Windows system right here I just have a git directory at the of my drive where I typically create all of my projects and we're just going to go ahead and create a new directory for us to work inside of and so I'll just do maketer Rust dock underscore learning right here and then we'll go ahead and open that up inside of vs code right here so we'll just do code at the CLI and then specify the path to that directory and that'll open up a new window so as you can see this is an empty directory there's nothing in there so we're just going to do a cargo init command whoops let me do cargo init and I don't know why I accidentally hit that so what we're going to do now is go ahead and customize our main.rs file here by adding some documentation before we actually add that documentation though I just want to show you what version I'm on so I'm on Rust compilerver version 1.72.1 that was just released about a week ago I think today is the 20th of September so yeah 1.72.1 is pretty new and so that's the version I'm running and then I'm also running a cargo version 1.72.1 as well of course those should match generally but I guess maybe in some cases you might not have matching versions I'm not sure but what we're going to do now is use the cargo dock command here so there's actually two different commands there's cargo Dock and then there's cargo doc test so um it's actually called I think that's what it's called anyways uh no it's not doc test I'm thinking of uh cargo rust dock yeah so rust dock is the CLI tool you can actually run rust stock by yourself right there without using cargo but again since I don't want to have to specify all of these input parameters directly to rust stock then I am just going to use cargo Dock and this cargo dock CLI here is just kind of a helper that passes in the kind of sane default Arguments for the CLI command here and if we take a look at the Target directory here sure enough you can see that we've got this doc folder right here so we have the debug folder that's where our project would typically get compiled as a debug bug release and then we would also have a release directory under Target if we actually built a dash dash release quality version of our binary but yeah the documentation is going to get published into that Target directory along with everything else now there's a whole bunch of files that get generated in here as part of the rust stock CLI so we are generally going to be opening up these HTML files and that's going to be kind of our entry point into the documentation and so right now we don't really have a whole lot in here because all we have is just our main.rs file and we only have one thing declared in our project which is the main function now one thing you're going to want to pay attention to when you're doing rust documentation or comment based documentation with rustdoc is you're often going to need to make your members public in order for them to be visible in certain situations and we'll kind of talk about what those are but if you recall looking at the rust stock book here there is a feature that allows you to link two items by name so if you're working with maybe two different child modules within a parent crate and module number one over here needs to reference something in a sibling module then in order for it to link to a function or a struct or an enum in the separate module that module needs to declare that type or function as a public member otherwise that link is not going to work properly so as you're working with documentation just kind of keep it in the back of your mind that public visibility is going to be necessary for certain features of rust stock to work all right so for starters here I'm going to go ahead and declare crate level documentation so this is kind of the root level documentation that we see at the crate level this is your opportunity to introduce your library to your users and kind of describe what the intent of that library is and how to actually consume it so you'll want to provide kind of a high level description a detailed description as well as a couple of just very basic code samples to show people how to kind of copy and paste those code samples and integrate it into your into their application rather so in order to do crate level documentation we're going to do a double forward slash and then an exclamation point here and this is called inner documentation because it's being defined inside of the crate and so it's going to apply to the outer item which is the crate itself so even though we're defining it inside of main.rs it's applying to the kind of parent object above main.rs which is the crate so we'll just go ahead and say this is some sample content for the crate level docs and then remember I said you can use markdown in here so let's say that we wanted to do a heading so we'll say introduction or detailed introduction or something like that right so we can do a double hash sign here to make an H2 heading we could use a single hashtag for a H1 heading triple quadruple and I think you can go up to like an H5 with markdown so feel free to use whatever specificity you want for those headings and then we could just say you know this is a detailed intro and we can do some other cool stuff too so with markdown we can make lists of items we can either use a dash to create a list item or we can use an asterisk to create a list item as well so we'll just say item one or let's let's do something a little bit more specific we'll do a heading here called features and we'll say this prate allows you to create person objects and I use person objects and animal objects and other types of objects in my applications to use as samples we could also say this create allows you to create grocery bills so if you saw from my last video we used grocery bills and grocery items as examples so we're just kind of describing the functionality that our crate provides now if you want to create kind of a checklist so let's say that you have future planned features that haven't been implemented yet then you can use this syntax where you put square brackets and then just put like an X inside of there to say all right this feature is implemented or we can do square brackets with no X in the middle to indicate that this is incomplete or we haven't implemented this capability yet so we can kind of create some future features here that we want to implement but aren't implemented yet and we can just check off the features that are or aren't implemented so this is create level documentation we could also also plug in like an example section here and then do triple dashes here and say all right construct a new person by doing person and then first name Trevor dot two string right something like that and then we'll go ahead and generate it so let's do let P1 equal person and then maybe print line and then do a placeholder and then do P1 DOT first name okay so that's a simple code example that somebody could copy they could construct a new person object assign it to a variable and then grab the first name field value and pass it in and substitute it here in the print line macro so what we'll do now is say cargo Dock and that'll go ahead and regenerate our documentation in that directory so now we want to do is open that path so what we can do is say cargo doc dash dash open and normally that would open your browser but there's some kind of integration on my system that's not working so what I'm going to do is just copy this link to the index.html file and we'll go ahead and just paste it into our browser here so as you can see right up here at the crate level this is kind of the root level of our documentation for this project here's the description that we provided here's the H2 heading detailed introduction it also has an anchor tag there so if you're sending a link to somebody and you want to link to a specific section in the create level documentation that anchor tag will allow you to accomplish that and then right down here under features you can see that we've got these two list items because we used a dash or an asterisk in markdown and we checked off one of these boxes here because we used those square brackets to indicate that we have a checklist of items you don't have to use the checklist feature with the lists you can just create bulleted lists without that but I just wanted to kind of show you both of those capabilities we can also do formatting like italics bold strikethrough text and things of that nature by using a few different markdown syntaxes so let's say this is outdated so don't use this okay let's say we wanted to kind of strike this out but we wanted to leave it in place so what we can do is use a double or single tilde character here around the content that we want to strike out and then if we just do cargo dock again and then switch back to our browser and do a control shift R to refresh you can see that we've done some strikeout text right down here so it kind of leaves the text in place but it shows somebody that hey maybe it's outdated maybe I should avoid going that route you can also do bolds like this is something really important you know this is a really important concept and then we can just do a double asterisk around here and then we could also do Emojis so on Windows you can do windows period on your keyboard and insert an emoji from the Emoji search feature here let's do something like an alert and insert a couple emojis then we'll do cargo dock again that runs almost instantaneously and so now we've got some bold text here and we've got a couple of emojis so feel free to use any of these markdown features and others that you might find in the rust doc documentation the the rustock book to kind of format and spice up your documentation and make it more engaging you know a lot of developers are really good at writing code but when it comes to documentation they might be thinking oh I'm an expert on this utility that I'm writing so I'm not going to go into a whole lot of detail I'm not going to do things from kind of a novice level so it's really important that you kind of guide people through how to use your crate and all of the functionality that it provides so use this create level documentation as that opportunity to really provide that beginner's intro to how to use your project and then at the very end kind of expand and say all right these are some more advanced use cases so feel free to drill into the separate module and use these more advanced features once you're ready and after you've already learned how to use the basic features all right so at the moment you can see that the only thing that we have defined in our project as far as types or functions traits that kind of thing all we have under this function is heading way down here is the main function you'll see this little lock icon next to the main function and this indicates that the main function is a private member of this crate so what that means is that this is not visible to other crates that would try to import this crate if it was a library obviously this is a binary project so what we'll do for starters is actually create a child module and then we'll start to declare some functions and types inside of that child module now I did a video on modules quite some time ago several weeks back so feel free to check that one out I'll probably do more videos on modules too because there are multiple ways to structure your modules but one of the simplest ways of declaring a module in Rust is to just use the mod keyword here so what we'll do is say mod people and this module is going to deal with anything about creating person objects maybe adding person objects together using the operator overloads that we talked about in the last video and so what we'll do for starters here is just Define a data structure called person and I use this commonly in my examples just because representing a person is a really common thing if you're doing you know medical records applications if you're building a CI CD pipeline utility that's a SAS based service and you want people to sign up for it you know you're going to be gathering this kind of information from people generally so we'll do last name string as well and I'm not going to go to to in too much depth with the fields here because we're mainly going to be focusing on the documentation aspect of it now as you can see we've got this message here saying people should be snake case so we'll go ahead and fix that with a lowercase and it's complaining that person has never constructed so that's not really a big deal because we don't care too much about that we're just basically focusing on the documentation now so what we can do if we want to document this module called people here well actually let's first start by not documenting it and if we come back and just generate our docs and refresh now you can see we've got this module section so that module section was completely missing because we didn't have any child modules but because we created a child module now it's showing us child modules that are declared within our crate so this module is currently private because we declared it as a module without using the pub keyword prior to it right so we can drill in there and we can see that there is a person struct declared in there and it automatically generated this entire document here showing any auto implemented traits as well as the individual fields on my data structure now I don't have any documentation for either the module level or the structure or the individual struct fields that I've declared so we need to go through and actually add that now I'm going to go ahead and make this a public module so that'll take away that little lock icon in the documentation I'm also going to declare the person struck here as a public type as well so that'll be a publicly accessible type from other modules in my project so now what we're going to do is specify some documentation for the module and I can do that with triple forward slashes here and say this module deals with people and person objects something like that and then for our structs down here we'll just do a triple slash and remember that the triple slash is documenting the object that's directly following it so in this case this comment precedes the module and in this case on line 29 the documentation here is preceding the struct so the triple slash means document the following object so we'll say this person struct represents a user of the system cool so let's go ahead and regenerate those documents and refresh here so now we're on the person struct type here and you can see that we now have some documentation that goes into detail as far as what this struct does we still don't have documentation for our Fields but we did add module level documentation so down here under the list of sub modules in our crate you can see that we've got a nice handy-dandy description field on our module so any other modules that we declare inside of our crate even if they are private modules we want to make sure that people know why those modules exist in our crate and we can do that by providing the high level guidance right here also if we drill into the module itself you'll see that we have more in-depth documentation here and when you're on the module list here you're not going to see multiple lines of documentation so if we had a really long set of documentation here that's introducing the module kind of like what we had up in the crate here let's do a detailed intro and say this mod has a person struct to represent users represent users and this module and be expanded in the future to deal with other user related stuff and of course I made a couple of typos here so let's fix those so now if we do cargo dock again and we switch back over to our browser you'll see that only the first line of the documentation is being used in the module summary but if we go into the details for that module we'll see all of the subsequent lines after the first line so when you're providing this brief description for your modules or any other types that you're declaring in here you want to make sure that you are using that first line as the kind of summary of what that module or type or function is doing and then you can always go into more depth in the future lines all right let's also add documentation to our main function here so let's go into Main and we'll do a triple slash and we'll say this is the entry point to our people application okay so now we've got some documentation for our main function as well and if we refresh you can see that that summary is displayed right there inside of our crate awesome so now we've got this module we've got a person struck in here we've got a summary for the person's struct but we can also document the individual struct Fields so let's go to our struct definition inside of our child module here and we can use the triple slash once again to specify documentation for the individual Fields so if you have some really weird field names which hopefully you don't but if you have something like fname I might not know as a user of your crate what F name means now I know it's first name because I'm the one who's creating this project but if you're coming along and reading you know Pub struct person F name is that first name is it Frank's name is it you know what exactly does that mean so we'll just add in a description here that says this F name field represents the first name of the person now notice what I did here so I used the triple slash to denote the documentation for the following field but I also use these individual back ticks to surround the name of the field and what you'll notice is that after we regenerate our documentation and refresh the page the amount of space font is being used to render this code just like you see in any code samples so anytime that you are referencing a field or a function name or an argument name or something like that that's kind of a well-known entity you can surround that in Bat ticks and that causes the markdown rendering engine to render that in a mono space font that looks like code that you'd be writing in a code project rather than a variable spaced font that's used for General documentation and reading purposes so that's really nice and then we can just kind of complete things out and say this is the last name of the person and try to avoid comments that just say like this is the last name field or this is the first name field because it in general it's really helpful to just kind of go into more depth like this is the last name of the person who's subscribed to My Cloud SAS service right that's a lot more explicit than just saying this is the last name field okay great but why do we need a last name well it's because they signed up for my cloud SAS and I need to be able to address them in marketing emails by first and last name right so try to be a little bit more explicit try to think of things from a novice user perspective when you're writing your documentation that's just a really good practice and so there we go we have documented both of those fields now we can also declare modules in other ways so one of the things that we can do as I've done in other videos is create new files here so I'm going to create another file here called animals.rs and then over in main here we're going to go ahead and declare that and you want to make sure that all of your crate level documentation right up here so lines one through 21 here these are all crate level documents because they're referring to the outer object with the slash slash exclamation point so what we're going to do is make sure that we go after that create level documentation and then we can do Pub mod animals and that will basically import the animals module in animals.rs into the scope of our main.rs file so now I can do struct dog you know breed string I could do struct how name string and so on and so forth and I can go ahead and document these types as well so this represents a how in my Zelda like game and we'll go ahead and save that and then do a document comment here that says this is the name of the cow all right so let's do cargo dock once again here and come back to our docs and if we go down to modules you can see we've now got a new module that's automatically been inserted here because rust is kind of looking at our project and figuring out what modules are declared so we'll go into the animals module and now we have two private Strokes because we didn't declare them as public and so for cow here it says this represents a cow and if we take a look at the details here we can see the documentation for that individual field so just remember that your modules in Rust can be declared as separate files they can also be declared as child code blocks inside of another block inside of your main project and there's actually other ways where you can create subfolders I forget what the exact name of the file is but you can create a subfolder for a module and then give the module a specific name and that will allow you to import that module from that alternate location as well so there's several different ways to declare modules in Rust but those are just a couple of them and how we can provide a documentation across different module structures now one other thing that we talked about is that we can specify documentation for that's that's external to our project here so let's say that for example in the main.rs file here I've got my main function that's the entry point right and so what I could potentially do is say that I want to include documentation in a separate file you know what let's actually do it for the animals.rs here so what I want to do is actually create a document for the module itself because we haven't actually implemented it at the module level if we go into animals right here you can see we don't have any module level docs so what I'm going to do is create a file here called animal docs dot MD and so this is going to be a separate markdown file and because it has the MD file extension my editor here vs code knows that this is a markdown file and if I have any markdown extensions installed or you can see this breadcrumb kind of situation going on here vs code allows me to work more intelligently with markdown inside of a separate markdown file than if I'm doing markdown inside of a rust document and so or a rust source code file I should say and so this is really nice because it allows me to separate my documentation but then I can import it into my rust code files by using the include string so let's do include Str rust and this is a macro that's part of the standard crate here and all we have to do is reference a file that contains the documents that we want and then there's a doc attribute so if we do Rust dock attribute you can see that we can use this in order to include a markdown file into our source code file so if we want to declare our documentation for the animals module separately then we can do that right up here remember the first line is going to be used for the summary though so this module contains various animals for my game and then down here under animals we could create maybe a subheading under animals for you know the cow type we could create documentation for the dog type and other types of animals that might appear in our game maybe there's chickens kind of running around the map as well in a in a some sort of game and so now what we can do is you know start to do things like plug-in code samples so how do I construct a cow so I'll do cow and then name is you know Nancy dot two string so we'll say let C1 equal cow and then we'll just do print line and then say C1 dot name and so there's another kind of code sample that we're embedding in our project so now what we'll do is go back to our module and what we want to do is specify that we want to include the documentation for the parent object here so what we're going to do is say Doc here and then include string so we'll say Doc and then we'll say equals include Str and remember that macros are executed at compile times when we compile our application the macro will basically expand to whatever it returns so what we'll do is just say dot slash animal docs dot MD and because this is being applied to the outer module we need to make sure that we do an exclamation point here because otherwise this will reference the following entity so if we try to use it right here then this would basically refer to the dog rather than referring to the module which is the parent scope that we want to apply it to so when we're using this we do an exclamation point just like when we are documenting the crate level stuff in main.rs here we can go ahead and just use slash exclamation point rather than slash slash which refers to the next item so back in animals here we'll go ahead and save this let's do a cargo Dock and we'll come back to our documentation do a refresh and now you can see that we've got module level documentation very similar to how we have crate level documentation at the root of our crate we can go into the child modules there's my little summary which is the first line of that separate markdown file and now I can see all of the subheadings that I've got right here inside of my markdown so it's really up to you if you want to embed markdown into your source code files or if you want to kind of extract and separate your documentation into separate markdown files and then import those with the doc attribute and the include string macro but this is certainly one way that you could accomplish it all right so we are moving right along here one other thing I wanted to show you how to do is to embed these code samples into your project tests so right now we have a couple of different code samples in main over here we have an example right here that says let P1 equals person and then we print the person's first name and then we also have this example in animals which is defined in the separate markdown file that instantiates a cow and then it just prints out the cow's name now I'm not necessarily sure if these are going to work and they probably won't because the cow is a private struct here but what we can do is say cargo test and this should allow us to execute any code samples that we have in our project here so it is going to compile our application here and then it'll attempt to run some tests now I think the tests only run if you have a library not necessarily a binary so what I'm going to do is go ahead and Define lib.rs here and we'll Define a struct cow with a name field here and then I'm going to switch over to animal docs right here and just grab this sample right here and then we'll go back over to live.rs and we'll go ahead and just paste this in so let's do a slash slash and then we'll go ahead and add our triple back ticks around the code sample right here and so now let me do cargo test and sure enough you can see that it did attempt to locate this test so I think cargo test is only going to work on the doc comments that you have in library based crates not necessarily application or binary crates that have a main entry point so as you can see our test did fail here it says cannot find struct and that's probably because it is a private struct let's just try to make it public here and see if that works and it's still saying it can't find so let's try to specify a use statement here so we'll say use self now see if that works and let me do a capital S self here and see if that works so I'm not having much success here let me try crate crate is another prefix that you can use and for some reason it's still not finding it and that's probably because I have a library and a binary in my project here but the point is here that you can see that it's attempting to execute these code samples inside of my project here and attempt to actually run that code and see if it works or not and then based on the failure of these code samples that are embedded into your markdown documentation you can choose if you want to abort the build entirely or if you want to you know do something else in your CI CD pipelines so you can embed those code samples another cool feature of the rust stock utility here is that we can actually enforce documentation across our project and this is where visibility of members comes into play so it's only going to enforce documentation for public members I'm not sure if there's a way to override that where you can force documentation for private members as well but if we take a look at our animals module right here we have Pub struct Dog and Pub struct cow in this child animals module so what we could do and let me just delete this lib.rs file here now that we've looked at the embedded examples in markdown and so now what we want to do is to enforce documentation for both the dog struct as well as the house struct so what we can do is use this special macro here called warn or you can also use one called deny and this will actually cause the builds to fail for a certain reason but I'll just do warn for now and we'll say Warn and then say missing docs so by using this we can enforce having documentation for our types in here and you'll see that immediately the rust analyzer extension in vs code is showing that we have missing documentation for a struct so that's going to show up in our problems pane right here and so we can literally just jump to these missing documentations so we can do a filter on problems and say missing documentation and then say all right I want to go over here and I want to document this type so we'll do triple slash this is the dog type that represents dogs in my game and as soon as we fix that you can see that that problem disappeared so we no longer have any problems matching that particular filter because our cow is already documented here you can also do a deny here so if we changed the warrant to deny and we remove the documentation there that changes the warning into an actual compiler error so if we try to do a you know cargo build here you're going to see that we have a problem with our build because we are enforcing missing documentation so if we bring that documentation for the dog type back and re-run cargo build you can see that cargo is allowed to build our project so feel free to use either warn or deny with missing docs and that'll help you to enforce having good quality documentation for your project all right so I think the last feature that I wanted to go over for now is going to be the feature that allows you to link to different types between your different modules so let's say for example that right over in our module that deals with people maybe we want a person to be able to have a an animal as a pet like a dog or a cow could be a pet in a game that maybe you're building or maybe you're building a real world application that allows you to manage ranches or something right and maybe a ranch owner has uh dogs and cows and horses and sheep and all that kind of stuff so we want to be able to go over to this people module that declares the person struck and then we could have maybe a field on the person's struct that represents the animals that are owned by that particular person right and so that's going to require us to actually link over to the animals module here and actually reference a type from this module now right now these are private types so we need to make sure that they are public so we're going to make sure that Pub structog and Pub struct's cow are there it looks like we actually already did that we just didn't regenerate the docs so let's just do cargo dock to regen and refresh and yeah sure enough now these are public types because they no longer have the lock icon there and so what we want to do is basically go over to the people module which is actually declared in main.rs because it's just a child block right here of course we could kind of extract that as a separate file so let's move the people module over into people.rs and then we'll go ahead and say Pub mod people from Main so now we've got people and animals as separate modules in separate files in our project and so if we wanted to create a field here like a VEC of animals so a single person can have many many animals right could be one could be ten could be 50 it doesn't really matter but we'll add in a new field here called animals and we'll make it of type VEC and then we'll do something like an animal trait probably so let's maybe go over here and say Pub trait animal and then we'll be able to implement that trait for multiple types but what we want to do is say VEC of type and then we'll do crate level animals and then animal trait so basically anything that's an animal will be able to be a member of this and I think we need to do the din keyword here as well and we also have a sizing issue here so let me think about the best way to handle this you know what for now we're just going to say that we can have a VEC of dogs and then what we'll do is let's just eliminate this here this trait and then we'll basically just say that we can have multiple dogs I'll um I'm having some issue with the dynamic dispatch here that I'll probably have to figure out later on but for now we'll just say that we have a VEC of dog as animals and let's say that in the documentation for this specific animals field here that we want to link over to the documentation for the dog strut so this will say these or this field points to all the dogs owned by this person so now what we can say is we could change this to Capital D dog and then what we could do is reference the dog type by using these square brackets so what you want to do is go to the documentation for rust stock and look at linking to items by name and what you can do is disambiguate by going to Crate and then animals and then dog so as long as we put this full fully qualified path just like we would do in a use statement then what we can do is actually link this documentation over to the public type which is dog right now this won't work for private types it will only work for public types at least based on the testing that I did previously so let's go ahead and refresh we'll go over to people here go into person and then find the animals field which is of type vect dog and then you see this link right here this will take us directly over to the animals module so now we're in the animals module and we're looking exactly right at the dog type here so this is a really nice way to be able to link from one child module that deals with people and then link over to a data type in a separate module that implements a different type that might relate back to the person type that we implemented in the person module this is a really cool feature that just allows you to kind of make embedded links inside of your project and make your documentation all that much more usable now keep in mind that if we change the visibility if we go over to the dog here and we make that a private member then we are going to have an error here because it says the struct dog is private right and we are referencing that from over here so this is actually a compiler error so if we were to comment out that field and then maybe let's say move this comment up to the person level documentation so basically I'm just kind of commenting out this fields to fix the compiler error and then we are still attempting to reference the dog type I think this is going to fail so if we do cargo dock here and then uh let's refresh the documentation for person type here so now you can see that this link right here with the square brackets it says create animals dog but this is no longer a proper link we can't click on it and this is because the dog type is private instead of public so even if we don't use the dog type as long as we make it public and regenerate our docs and refresh the page you can see that the link is now working so hopefully they add support in the future for rust stock to link to private types across modules but for now that doesn't seem like it's possible using the Deep linking feature in Rust dock now another feature that you can potentially run into is having conflicts with types so type names I should say so let's say that our animals module here actually declares a public struct of dog but we also have a pub FN called dog as well and I'm not going to do anything inside the function body here but you can start to see the issue here where we have a dog struct and a dog function but in the documentation for our people type over here we're pointing to dog and we're not really specifying if it's a function or if it's a struct or a trait or an enum or whatever so if we refresh the docs here you can see that by default it's going to point to the dog struct here but what if we wanted to link to the function well what we can do is prefix the link with FN at and that will force it to link to the function instead of to the struct so now when we click on this link it's going to take us to the dog function in the animals project rather than the dog struct we can also force it to be the struct by specifying the struct at keyword and then regen that and now if we click on that link it's going to go back to the struct we could also potentially have a trait so let's say that we had a trait dog here I'm not sure if it's going to allow us to do that since we have a type in there so yeah we can have a trait or no it's not so the compiler is going to complain because we can't have a struct and a trait with that name but just to show you really quickly if we had a public trait of animal and say this is the animal trait that applies to all concrete animal implementations so now what we can do is link directly to the trait by using the trait prefix as well so what we could potentially do is say that this field points to all of the trait at create animals animal trait and now we are referencing a trait in the documentation rather than a function or a struct so let's do a cargo doc gen again and if we refresh now you can see that this link is actually pointing to the trait called animal and we're being very explicit about that because we're using the trait at prefix here so you can use you know function at as a prefix enum struct trait as a prefix and 0.2 specific items that are declared in that Target module that we are attempting to link to so feel free to use that technique to link between things in your project and also check out the documentation here to find other supported keywords you can also use the super keyword the self keyword and things like that as valid links within your rust documentation so anyways I think that's everything that I had for this particular video if you made it this far thank you so much for watching there's lots of great features inside of rust stock there are some other features that we didn't get a chance to cover in this video as well but I'll save that for a future video that goes in more depth into rust doc again just please if you enjoyed this video make sure that you come back to my channel youtube.com Trevor Sullivan subscribe like the video and leave a comment down below and check out the links in the pinned comment if you want to support my channel thanks so much for watching and we'll see you in the next video take care
Info
Channel: Trevor Sullivan
Views: 2,831
Rating: undefined out of 5
Keywords: rust, rustlang, rust developer, rust programming, rust software, software, open source software, systems programming, data structures, rust structs, rust enums, rust coding, rust development, rustlang tutorial, rust videos, rust programming tutorial, getting started with rust, beginner with rust programming, rust concepts
Id: G2_Tb2f2F1s
Channel Id: undefined
Length: 53min 44sec (3224 seconds)
Published: Thu Sep 21 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.