Starting a TUI Rust Application - A Postman Alternative

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome back to the g rush Channel I'm buddy Lindsay and we are going to be starting a brand new project and it is going to be a twoe app a Tui a terminal user interface app and you might have a little bit of a familiarity with those uh when something like lazy get I've not actually used this app but this is kind of the idea behind it is you have different sections here and it's like a US user interface uh to be able to do a thing and in this case lazy G is doing get and apparently is very full featured and uh so that's that's what I'd like to create except what I want to do it is based on and I should have pulled up is this post I should have pulled this link up earlier like Postman and other alternatives are nice but they're they suffer a couple of problems they get bloated quickly because they are uh web you know they're like react native or whatever um electron apps um then there's that constant fight to add features and add features and then it's the we've added all these features and now we can go get $100 million in venture capital and we can do all these other things and so I don't know they kind of lose direction and I am not saying that won't happen with this application but I would like to make an attempt to keep a slim down version as a terminal user interface app a 2E app that does web requests and I just want to Simply start out you can choose a post you can choose a get you can choose your basic HTTP verbs you can make a request and you can get the response and you can view that and you then you can also save those things uh to your computer to pull back later I'm not going to do team collaboration stuff right now um that that I wouldn't necessarily want to do that per se anyway all that stuff is a material I want a basic application that lets you query web interfaces via an application and save those results that's all I want might add more stuff later but right now this is all I want and so let's build that as a as a web based application we're going to do it in R so it should be blazingly fast and hopefully we should be Go I mean we've already done a few things towards that direction in previous videos specifically we use the request library and that's kind of going to be a Workhorse of this and uh yeah so let's see about getting started to do this again this is kind of interesting what it's going to look like but I want to use a library called Ratatouille um this is a rust Library um application module whatever uh crate uh for doing twoy applications so normally I would Chum to jump to chat gbt and be like yo give me give me everything that I need to do to do X Y and Z however I feel like we're we're we've moved down a direction that uh we don't need to to do that per se so what I want to spin this video to do is I want to try to build out the user interface but I want to follow some of the tutorials on the Ratatouille website uh just because there is a particular way I I've browsed some of the website some of the uh documentation and one of the interesting things is that is not what I wanted to I do want that but not that that was not what I was after yes one thing that is interesting is is it here nope Concepts yeah uh rendering rendering yes so I thought this was interesting the the type of rendering that the system does um apparently there's two different paradigms uh that exist there is retained mode rendering and there is immediate mode rendering and retained mode is your traditional like Wind forms web form you know iOS applications that you write State and whenever something changes you get get a draw event and that widget draws whereas in mediate mode every you redraw basically every Loop and the widget is not permanently in you know the thing is not like retained with State somewhere for that particular thing think of this think of immediate mode basically is a game you have a loop that is constantly going and you drawing out that interface and so it's kind of an interesting way to approach doing uh the user interface for this so uh that's another reason to kind of read some of the documentation is we're going to have to think in that realm in that way so had a had a viewer jump on and then jump off but I did have one today so all right uh let's look let's start or go to the tutorials I actually want to jump ahead we have a Json editor and and we want to initialize so I've done the counter app and it gives you a basic structure uh to get started and and it's not really an advanced one the Json editor I didn't go through all of it but it gives a better structure for how to start our application and and architect it um and one of the things that I find interesting about and a little tough about rust is um raw rust you can do whatever you want um and it's hard to choose what library know what design pattern or architecture your code needs to take and so when you can use something that kind of like helps move you in the right direction then you have that opportunity so um we're going to go through J the Json Editor to do the few specific sorry we're going to go through this tutorial but we're going to tweak it for our needs so that we come out the other end with a good base to start our main application also this gives us an opportunity to learn so the first thing is let's just copy this okay this is not what I want so let's do we're going to do a new session control W uh we're going to do tuy Rust toy go with that CD dot dot um what do we want to name this application I want it to be let's do Rust new rust new two we post I don't know I I we will figure out a better name later but we'll just go with that for now what cargo gosh got flustered because of something that just happened a little bit ago so let's cargo new to post all right then we want to do cross term Ratatouille see cargo add cross term roui sir no then we're going to do uh let's just do that oh might help if I CD into it there we go and then we want to do cargo add sered features equals drive and then cargo add sered jonon cool we're NP we're car hey P there we go cool cool all right kill that all right so we have our new we have these so now we want to make sure we have these files so main UI app uh Source no touch hche Source ui. RS and app. rs right m should already be there ui. RS app. RS cool cool all right so as we saw in the previous section common models were smaller right two applications have one application called an app or some variant of that uh this structure this struct will contain all of our persistent data interesting and we'll be passed application modes did you s to think of think about several modes that your application can be in uh thinking in modes will make it easier to segregate everything from what window is getting drawn to what key binds to listen for I will be using this application state to track two things what screen is the user seeing and which box should be highlighted the key your value this one okay current screen enum in this tutorial application we will have three screens main editing and existing interesting uh the main summary screen shows all past key value pairs enter the screen shown existing editing the screen shown when user wishes to create a new key value pair and exiting displays a prompt asking if okay main oh okay okay okay so this yeah yeah I'm with you there okay so we have the current screen enom yeah so main is just like the display of what's happened in the past editing for this application is I am editing some Json that is saved somewhere or whatever exiting is like are you sure you want to are you sure you want to uh exit yes uh as you already know RIT to does not automatically redraw the screen RIT to also does not remember anything about what it drew last frame Yep this means that the programmer is responsible for handing All State and updating widgets to reflect the changes basically like game programming like I said will will allow the user to input two strings in the editing mode a key and a value the programmer is responsible for knowing now that we have okay what okay feel like I'm missing oh app. RS this is what goes in app okay I totally missed that mhm so let's copy so that's our current screen uh currently editing currently editing as you may already know red to is not automatically WR okay this means that the program is responsible for handling all state and updating widgets to reflect changes in this case we will allow the user input to input two strings in the editing mode a key and a value programmers resp responsible for we're just going to do this thing and then we're going to back it out to what we need cuz I am a little bit lost is how this is going to work but let's talk about each step so that we make sure we understand what it's doing okay so the full application State now we have enums to track where the user is we will create the struct that actually stores this data okay yeah so key input currently being edited Json key the value input currently okay the pairs representation of the key current screen okay so I think this is specific to Json editing current screen the current screen the user is looking at and will later determine what is rendered okay currently editing it's an option State containing which of the key value pair uses okay so this is probably going to be needed helper functions um while we could simply keep our application status simply a holder of values we can also create a few helper functions which will make our life easier elsewhere of course these functions should only affect the application State itself and nothing outside right so so we have our struct we want to implement our app so we're new so we create a new application implementing a new string and a new hashmap pairs current screen main okay that makes sense and then we have uh save key value okay so in this case it is adding the key input and the value input that the user gave to the pairs and then resetting it and setting currently editing To None okay toggle editing okay toggle editing if let some edit mode self. currently editing match edit mode currently editing I miss this is going to be a struct or an enome that use what if it's not edit mode just show I don't actually understand what this is doing off top like currently sometimes it's easier to put simple logic into a convenience function so we don't have to worry about it in the main code block toggle editing is one of those cases okay I guess that's what it's doing we'll come back to it I'm sure there's other code that will make that easier to understand okay so in this case print Json s Json self. okay I mean that makes sense like it's just going to Output it I like it okay main RS okay so this is the actual like where we set everything up um so let's go in here copy this so enable raw mode this if I recall is can I'm not I'm not even going to try to explain it I don't remember that well because application takes whole screen and captures all of the keyboard input we need some boiler plate at the beginning of our main function uh you might notice that we're doing standard error for output this is because we want to allow the user to pipe their completed Json to other programs like that yeah to do this we utilizing the fact that standard error is piped differently than standard out and rendering out project and standard error and print out completed Jon and stand it out what to do this really but Standard air is piped differently than standard out and rendering out project in Standard air oh yeah yeah so yeah instead of so yeah what the crap just happened so in Linux you have three file descriptors file descriptor one is zero crap I'm forgetting the name one of them I think it's I think it's one is yeah is standard out and file scriptor 2 is standard error and so your application is going to be like hey I just want to run standard out it's going to grab that file descriptor of one and then output the information to that same thing for standard error if you have an error um you grab the file descriptor 2 and then you file you write to that file descriptor file descriptor is something simple that whenever you're doing a uh like you're doing an open uh file.csv uh then in say C what you're going to get back is a file descriptor you're not actually going to get the thing back um and then in this case you know file descriptor would be three uh or the next lowest um file descriptor that's available uh and then from here you would do actually I can't think of what you would do off the top of my head um but anyway from here you're referencing a file descriptor not the actual file itself that's just how it it all works anyway so in our case we the application is saying hey we want to render out everything to standard error because when we do a thing later we want the user to get normalized output to standard out the file descriptor of one anyway quick little lesson on file descriptors and Linux and how standard outstander kind of took me a while to to to really understand what was going on on that uh and then one the other thing is ratu outputs to cross term uh for some for its rendering so that's why we have to do this next part we have to set up our backend it's going to render out to and we're passing in standard error um then we're creating a new terminal if I recall let's see anyway uh and then we're creating our app that we're pulling in see oh crap all right uh since our RIT to application has changed state of users terminal with with our pre-run boiler plate we need to undo okay let's just copy this because it's going to get stupid no oh that is actually not crap let's go here yeah this is where I'm shooting myself in the foot this is what I hate about tutorials online sometimes is they they give you the stuff that you can do but they don't give you the uh all the Imports like there we go now let's come up here boom oh look there's a bunch of crap here that is not imported let's do use cross term all right use IO got to figure out where these dumb Imports come from hate I hate Imports and applications because of this right here I don't know where they need to come from I don't know where stuff comes in one reason I like python is it's actually bad practice to not explicit tell you where a thing comes from I like C as as a programming language I hate that I can import a nam or I can use a namespace and I have no freaking clue what's in that namespace unless I go look up documentation somewhere it absolutely drives me bonkers uh dealing with Imports and applications like this is basically a very basic thing and I'm just totally freaking screwed on this like I I just want to follow a tutorial and a freaking work like what the crap cross turn back end might not even be in Cross term you know what it might be in rouille yeah should have known that like anyway uh and then you've bent no what is this I don't I've seen this in a few places in other tutorials I I have seen or rust some import Prelude thing what is it doing Okay cool so all items Prelude Prelude right it to a Prelude that's oh my freaking gosh that annoys me where do run app come from okay that's our own function e he we're getting closer all right I think I work through import issues okay so in this case let's get it let's see create app and run it so that's the app that we're pulling we need to figure out that import worry about that in a minute uh okay I don't I don't know I'm restore okay so one thing on terminals is we got to create a new terminal to run everything back and then we have to so crap any right we're going to actually back off that terminal backend mutable leave terminal show cursor all right we're going to create our run app feel like this is not going to be a fun one here and then we're going to get our event handler then main screen and then exiting editing interesting I'm kind of gathering a little bit as I go through here but not a lot oh were you kid okay okay here's where we're going to do Weg all of this copy paste sweet and then we're going to break it down UI is huge okay let's just do cargo run not found in this scope there we go create [Music] uh here we go to Bar Q yes cool so it worked on application works abort abandon give me a second here be honest it's a little bit of a rough night streaming definitely getting into areas I don't understand all right so let's let's go break it down let's break it down let's look at source Main so these are all the Imports that I was complaining about I still wish they would have put those Imports in at the beginning of the tutorial so that I could like copy and paste and type things out and move along at least we have them here now so enable raw mode let's look at what raw mode let's do this all right by default the terminal functions in a certain way for example it will move the cursor to the beginning of the next line when the input hits the end of a line or that the backpac is inter interpreted for the character removal sometimes these default modes are irrelevant and in this case we could turn them off this is what happens when you enable raw mode those modes will be set whenever see oh enable input will not be forwarded to the screen and input will not be processed on enter input will not be line buffered special keys like backspace and control c will not be processed okay and new line characters will not be processed therefore print line can't be used use right instead interesting good note good note okay so this is entering raw mode so that we can do our thing we can create the 2E application so then we want to execute everything on standard error we're going to enter the alternate screen a command that switches to alternate screen commands must be executed cued for execution otherwise okay enable mouse capture sure command that enables mouse event okay these are awesome docs uh so this is saying we're want to use cross term as our backend there are other options terminal and interface to interact and draw the frame this is the main entry point for Ratatouille it is responsible for drawing and maintaining the state of the buffers cursor and viewport the terminal is a generic is generic over a backend implementation which is used to interface with the underlying terminal Library okay so this is the start of brage R here provides that abstraction on top of the uh back end that you choose this is our application and then we're going to run it and then I guess once it's done we're going to restore raw mode wonder what backend mut gets the back end is a mutable reference I could have guessed that from the name but what does that mean like what is it doing uh leave alternate screen disable Mouse capture okay so this is just setting it back terminal show cursor yeah I mean I think that's shows the Cur yeah give the cursor back I guess uh if do print from your from our respon then we print the Json if dprint where's dprint okay dprint I am missing something do print okay okay dprint we have a response oh run app response from up here then we check if okay and do print is true then we take our app and we print Json otherwise there okay man I was like woo all right this is our running application so this this all of this was basically boiler plate to run the application this is the thing that I wanted to work on this is the thing that I wanted I wanted to understand here that this section is actually running our application if we want to Output anything for the final user then we do that here but we need this and we need this for every application that we want to run that's what I wanted to know that was one of the reasons I wanted to do this the other thing that is provided from this is like hey here's how you can split up and separate some of your code so in this case run app this is the event Loop if we think of games so we're do Loop actually not seen that before whoa is that 80 yeah that's 80 lines long it's awesome okay so this is the vent loot is that like a what is the loop in rut Loop keyword used to create infinite Loop nice this is a control flow structure that repeatedly executes a block of code independently until explicitly told to stop usually with a break okay let mutable counter continuing to the next iteration whatever okay they there's doing like count the clarity of intention when using when you use a loop it's clear if the loop is intended to run indefinitely I like it I like it I do like that that's a cool thing the loot body is guaranteed to execute at least once unlike a while CU a do while those are generally executes once anyway control over exit points l Loop allows multiple conditionally pred breaks useful situ care all right cool now we understand that so now we're going to do a draw FF what is UI F it's closure I don't know what it's passing it draw synchronized terminal size calls rendering closure flushes the current internal State and prepares for the next draw call okay so it erases their inocence uh the changes drawn to the frame are applied only to the current buffer after the closure returns so f for frame now okay okay that makes sense passing in the frame and then the UI it's coming from our UI over here which so UI here function public function UI the mutable frame and then the application we're doing yes gotcha okay if there is any so we have drawn the frame if we get an event and let me one second okay cool so these are to process all key events that we want to do something if we have a key that has been released we all yeah we only care about press man this is so much like a gaming interface like we only care about presses we don't care about releases but you have the option uh so match app. Curren screen how far is this match all the way to the end okay so if the current screen is main match the key code of e then current screen is changed to editing which is which is an enum yeah current screen main editing ex exit exiting and the app currently editing key okay so we're currently okay so this is setting the input that we're currently working on to be key currently at because we're currently editing the key or the value so in our case we would potentially do this is going to get complicated this is going to be interesting we would do potentially like the post or something we'll see I think this is going to go through some iterations this is going to be a fun time this is why I wanted to start a complicated project is I wanted to be able to learn and stretch and so yeah so if we're doing so okay so if it's doing an e it's going to switch to editing mode and it's going to go and set key is the thing that we want to edit okay if we hit Q then we're saying hey we just want to quit current screen is going to be to the exiting screen and we're gone so if we current screen is exiting and we hit Y then we return true we hit n we return false if the current screen is editing and we press a key down key kind key event kind key event kind up there on line 66 up here is a release okay then we're gonna whoa crap then we're going to match the code that was pressed and if that key code was enter okay man okay if the key code is enter I don't know where editing is coming from let some editing come from the reference to currently editing I don't understand this code like I I really don't understand this I'm just being frank like this little chunk here I don't understand let's let's move on so if we look at like 1919 here if it's Escape then the current screen goes back to Main and currently editing is set to none tab toggles the editing which does one of the things key code care represents so it's just any so if it's a character like ABC okay okay because because we want to validate since it's Json okay so if we press something and it's a string it would be string C syn says some validation okay then app. key input what is a hashmap I think or a string apparently you can push a string did not realize that but you would push the value currently editing I'm still like I not understand this app currently editing is an option uh okay so we have option currently I think that Pub currently adding uh I wonder if this is instantiating a new [Music] uh currently editing okay enum it's an enum though optional State yeah I don't I got to copy this can you explain this code to me it's just over my head like it's referencing the enum here that is an optional enum and if there is something there we want to match what that result is and if we're on the currently editing thing and it's key then we're going to add the value to our key input string or if it's currently editing value field that we're going to push the value into that string but currently editing is an Eno is it not currently editing is an enum so no it's not an enum it's an option en know that can return some I can feel my brain stretching trying to understand this okay let's see what jiid tells us all right sure the rust code St an example of using a pattern matching with the IFL and match con constructs to handle different types of data within a structured possibly gooey based application man that's so creepy sometimes that Chad jib can figure some of that out okay if let construct syntax is a convenient way to combine if and match for cases where you only care about one of the possible matches it is particularly useful when working with with option and result types inside of the IFL there is a match yeah checking to see if some editing can you rewrite this as just a match check okay app. currently editing is checked to see if some editing if it is editing is bound to the value sum and the code block if execute the ersan suggest that is an option type and being borrowed rather than moved yeah which allows other parts of the code to use yeah okay um okay this is the part that I was after okay so the IFL is basically saying match what is set to currently editing if it is some do your thing if it is none do nothing so the if like yeah is is synta is syntactic sugar okay that makes more sense so if we go back over and we come back over here sure right here fine whatever okay so now we're in the case we're checking the currently editing enum value that's optional if there is something set then we do this next match okay so if it's that if let like because it's setting okay that makes more sense than it did I'm good with that this is a mind Bender and then we do all that stuff not going to worry about that okay we have our app go to UI and that's a lot of stuff let's not worry about that I mean UI let's Che layout default returns default value for the type default values are often so Direction vertical I think that's going to build it vertical uh yeah it's probably like a packing thing so we might play with that a little bit to better understand constraints a length of three I we'll play with that as well block with borders some sort of style a title create new Json styled with that okay frame. render widget okay with title and where did chunks come from chunk chunks chunks chunks I guess that's the layout what what okay and then list items we're going to put everything in the list item app pair okay app pairs from replication these are things that we are added want to list the item list item is a widget and a line and a span and a style and a format and all this other junk so that we get the outputed list then we get a new list oh list items is a mutable list item that we created the VC here we populate that Vector then we create a new list from the list items man this is really reminiscent of Wind forms um then we render that widget okay I think that makes more sense mode for a I am getting this I think I have a good sorry I don't have a good anything I think I have a rough idea of what's going on so next week I think what we're going to do is we are going to play with layout and see if we can't get something going from that with some dummy data I have a little better understanding of what's going on and how things need to be constructed together but we definitely have some work to do this is going to be an awesome project uh to learn from so definitely stick around and I will see you next time where we're going to make some progress on layouts have a good one
Info
Channel: GoRust
Views: 1,898
Rating: undefined out of 5
Keywords: rust console, rust programming, ratatui, tui, rust tui, rust ratatui, learn rust, diy rust, programming, rust programming language, rust programming language tutorial, rust videos, rustlang tutorial, rust development, rust, rust developer, learn rust programming, rust language, rust concepts, getting started with rust, rust tutorial, gorust
Id: PMHyZEtzHcA
Channel Id: undefined
Length: 63min 56sec (3836 seconds)
Published: Tue Apr 16 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.