Also 1:55, showing us alternate keybinds and unexpected output rather than cutting it. Your rust memory editing dll is the best tutorial I've seen so far
Code's here, errata is below: github.com/fasterthanlime/axact I used an auto-subtitle that transcribed "serde_json" as "Sir De Jason" and I don't know if I'll ever recover. Correction: the front-end world is not a mess at all I don't know what I was thinking haha don't shun me plz Correction 2: std::thread::spawn would've been a better choice than tokio::task::spawn_blocking for a background task that never returns. Correction 3: the next version of Axum will ship #[must_use] on the Websocket's response, which would've caught the "load-bearing semicolon" bug: github.com/tokio-rs/axum/releases/tag/axum-v0.6.10
Dude... the amount of stuff you know... I've been in backend programming for years and have done some js in the past... but man... never in a million years would I be able to jump into the multitude of stuff you just did, especially debugging the websocket issue. Truly impressive.
So this is a lot more prep work than is visible from the edited version - I spent a half day before that building a way more complicated app! This was shot a couple days after, so it was still fresh in my mind. There were one or two dead-ends while recording where I had to reset, so you know - room for improvement 🧐
I usually hand-subtitle my shorter videos. For this one, UA-cam's auto thing was taking forever so I used github.com/m1guelpf/auto-subtitle which is powered by Whisper and - I'm pleased with the results. ~1.5h of fixing them by hand would have made them perfect (much less work than captioning everything from scratch) edit: I fixed everything, but it was more like 2.5h 🙃
Your coding videos are a breath of fresh air, and amazing content. They include the right amount of “what is he doing here?” to spark immense motivation and curiosity to do this while still being understandable enough to follow. Please do more of these!
You're an excellent coder! Your video is amazing. Many thanks and please continue sharing your knowledge. UA-cam is filled with numerous "programmers," but you stand out as the only one who provides truly informative and practical content. Much appreciation!
You taught me a lot of things I didn't know in this video. (Even some incidental stuff like the -F/--features flag in cargo add was new to me, too.) Thank you for sharing! I haven't finished watching this video quite yet, but I just had to say that I genuinely laughed when you discovered that unit implements IntoResponse. That's such a sneaky bit of unexpected behavior!
Though I can also code with that speed but, his pace is really insane, I can't react the same as he did, cause if it's me it will take at least a second to process and read the errors/warnings.
19:25 I would just add the "defer" attribute to the script tag so it is fetched in background and run after dom loaded! ;-) PS: Then the double slash in beginning of fetch. Haha, I am glad I am not the only smart persons doing such mistakes.
Wow, really interesting video, before watching I’d thought that 50 minutes long video will be boring, but I’d been wrong, it was very informative. Hope you will make more videos in this style in the future, I really like it. Thanks for your efforts!
How much of you being so fast is editing, and how much is a genuinely ridiculous typing speed? You have a really efficient workflow, by the looks of it.
When I shut up it's editing, when I talk you can see how fast I really type. I'll do a WPM test on stream one of these days, if that's what the people want.
@@fasterthanlime I think this is more perceptible when editing code then on a WPM test You not only type fast but you know your hotkeys and combos, so you reach your goal much faster then if you typed everything and the part that you do type is very fast
It is a pretty normal typing speed, idk what you are talking about. What part was ridiculous? I never thought that I am a power user or anything, but I also use VIM (motions) and WM (awesomewm), not even remotely to the max efficiency, yet I am around the same speed. You guys are much slower? I think it is around average in our world.
I bet a lot of that speed actually comes from the Vim extension. How he moves through the document still looks like insanity to me though, even as a full time Vim user xD
Even without considering the use of vim keybindings, his typing speed is unbelievable. To prevent bias, try typing directly on a typing measurement site and measure your speed. Even though I feel much slower than the typing speed shown in the video, I still rank in the top 3%
BTW, at least on Linux, when you ask for the CPU usage you essentially get the number of ticks that the CPU was busy/idle (+ some other states) since boot. If you want to give the usage in any given period, you need to know what the ticks were at the beginning and the end, and then subtract one from the other. That's what this library will be doing under the hood somehow. I personally think it makes more sense to have an API that requires you to sample at two points in time and gives the average usage in that interval (or Duration in Rust lingo). Otherwise you're getting something that's making a whole lot of assumptions about how you want to do this sampling.
I was wondering more about your pc setup, do you have a list of hardware/peripheral/apps you use? Workflow feels super smooth and responsive, would be great if you share the info! Thank you
I should probably make a video or article about it because the question keeps coming up. You can check my latest AMA on /r/fasterthanlime (reddit) that has _some_ answers.
I would love an article on how frameworks like axum and actix-web create those handler functions that seem to detect what their parameters are and inject the correct things. It's a technique that may be useful for some other scenarios but I have no clue how it works.
Essentially Axum defines a Handler trait which is implemented for functions with certain signatures. It involves a lot of code repetition in the library which is done through macros. It looks like Axum implements the trait for any function between 0 and 16 compatible parameters. If a function had more than 16 parameters the "magic" would stop and it couldn't be used.
Incredible content ! Didn't see the 50 minutes go by ! ^^ Rust is amazing ! :D You could've done your front in webassembly to have a 99.9% rust stack ;)
Just a heads-up about the code around 21:50 where you introduce preact - I'm not so sure preact handles multiple render() calls to the same root in an optimized way. There's nothing in the documentation that describes its behaviour when rendering to an already-rendered-to root, and it's certainly not the intended way to update the page. It very well may be re-building the whole DOM each time your update() function gets invoked, basically as if you had chosen not to use Preact at all and just generated some HTML in a template string or something. See e.g. preact issue #436 to confirm that this is not an intended use, though it is an old issue. The current documentation mentions a to-be-removed special third argument to render, specifically for replacing an existing root. editedit: I checked the source as well and it seems that, yep, it just rebuilds the entire Virtual and Browser DOM if you re-invoke render().
Awesome video...!!! Coool VSCode Setup what extensions do you have and what editor configs have you applied....ridiculous typing speeeed...Loved it!!!!
Thank you so much for this informative and well-explained tutorial! 🌟 Your guidance on setting up a Rust backend with real-time WebSocket communication and integrating it with a Preact frontend has been incredibly helpful. I especially appreciated the hands-on examples and clear explanations. I've subscribed to your channel and liked this video as I found it very valuable and am looking forward to more of your content! 👍 I was wondering if it might be beneficial to explore error handling and reconnection strategies a bit more, particularly for the WebSocket connections. For example, I got 'Error sending message via WebSocket: Error { inner: Io(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }) }' panic error when refreshed the page. Implementing graceful error handling on the Rust side (instead of '.unwrap()' ) and adding automatic reconnection logic in the JavaScript code (not only .onmessage, having .onclose, onerror as well) could further enhance the robustness and user experience of the applications built following your tutorial..?
@@baggern No the point is if you get in the habit of putting in the "return" it's better. It's way easier to notice a missing "return" than a missing semicolon.
For the mutex version, would it have made sense to use RwLock instead of a Mutex? Because then multiple requests can have read access at the same time to the CPUs
At 34:52, i see there is a mutex lock. Is there a scenario where we dont care about the accuracy, for instance, can we simply just read whatever value that is there, and skip the whole locking? Do you have to use a different datatype for this, or does this defeat the purpose of how this setup is intented to be?
I've never seen instant legacy code being written in Rust before. I get it, it's nice for showing concepts and else, but this can't be said to be good code at all. Reminds of the glory days where people were doing tutorials where they store structured data in unstructured data store with their MEAN stack and call it a day.
@fasterthanlime, I wonder if you have hints as what you did to make you feel so comfortable in programming with Rust. I like how you've been able to articulate things rather quickly with effortless familiarity. I'm aiming to achieve similar mastery of the act. What do you suggest that one can do to achieve such?
I love how fast you are with vscode. Do you have a reason why you use vscode over neovim? and also maybe you can have a keyboard logger on the screen, so that I can look at what shortcuts you are using.
I use vscode for its remote editing feature (this is all happening in a VM). A TUI editor like vim/nvim over SSH isn't the same thing, especially when there's latency involved. Also, the plug-in ecosystem is fantastic and most of the time it just works (VscodeVim has been shaky lately).
@@fasterthanlime thank you for the reply. what service do you use for the VM? that's actually really smart to just have a separate VM for programming because wsl2 takes way too much ram.
@@fasterthanlime Yes exactly, thanks! But like ciso said, I'm also interested in the long version, if you have the capacity of course. Great content btw, I always enjoy your videos/blogs.
I use a tool called AltDrag: stefansundin.github.io/altdrag/ - it still works on Windows 11, but you have to change some options for HiDPI displays and I need to restart it whenever changing the display config.
Hey Amos, I'm pretty sure the tokio people recommend not putting never ending tasks into a spawn_blocking because it spawns onto a pool and thus you permanently reduce the pool size by 1. Instead they say, just spawn a regular std::thread here
Wow how u type and move so fast on vs code 😮 And it’s fun watching u 😂 ur amazing I want to learn rust do you have any advice I worked with node and react and I want to jump to something else 😂😂 Maybe java and spring or rust 😅
If loading JS from a file, I think it works easiest just to defer it? I wonder if this would've been fun to implement with tokio::sync::watch. I feel like this is such a good usecase for something like that. Where one thread can update and send on the channel, and any thread that reads it for an API call can just get the latest value. This uses a better lock I think? I'm not really sure. Edit: I got to the point in the video where you used the broadcast channel lol
So because there's a fetch / a WebSocket request it might be just getting "lucky" with the DOMContentLoaded thing and we might still need an event listener, I'm not sure. Or maybe modules always run only when the DOM is ready. watch would be better than broadcast here, I didn't think of it in the heat of the moment!
At 33:35, we pass different copies of app_state to axum router and to spawn_blocking closure, but changes to the "copy" inside of closure are somehow reflected at the router app_state "copy". Don't know why this works and it confuses me a lot 😕
This is because the AppState struct only has one field, which is an Arc. Arc implements Clone, so because all fields implement Clone Rust can derive the Clone impl for AppState with a macro. The Clone impl for Arc doesn't create new copies of the data, it just returns an extra reference to the underlying data - Arc being short for "Atomic Reference Count". The Atomic part means the count can be safely updated by multiple threads (it is both Send & Sync) , as opposed to an Rc (just Send I believe), which would be only for a single thread. Usually that would mean they are all immutable references, as the borrowing rules state that any shared references must be immutable, and only exclusive references can be mutable. This is why the Arc wraps a Mutex - Mutexes are one of the Rust types that use interior mutability. This means you can obtain a mutable reference via an immutable one. Mutexes enforce borrowing rules at runtime by guaranteeing there can only ever be a single mutable reference at any given time. This is achieved via some type system magic where a thread can lock the Mutex, which returns a MutexGuard, and whilst the thread holds that guard it will block other threads from locking it. The guard type is what actually provides the mutable reference, and when it is dropped the Mutex is free to be locked again by another thread. So basically the Arc means every clone just returns an immutable reference to the same Mutex & underlying data, and the Mutex allows those immutable references to be turned into mutable ones. The data is never copied anywhere. Hopefully that made sense? If you'd like to learn more, have a look around for resources on "concurrency primitives" - Jon Gjengset has some great videos on Mutexes and other types, there's plenty of blogs around, and the "Rust Atomics and Locks" book by Mara Bos is an excellent resource that explains all the nuts and bolts in a practical way. You can also dig into the standard library's docs for the types & traits mentioned, they do a decent job of outlining things usually!
@@Rozza3 Oh, I didn't realize that traits of struct fields can implicitly affect the struct in that way. That makes sense now. Thank you for such an elaborate answer. I'll definitely check the "Rust Atomics and Locks" book 🙂
@@JuanDelS Ah, that particular magic is the "[derive(Clone)]" part - only derivable if all struct fields implement Clone, which is true for the Arc in this case. The derived Clone impl will just call .clone() on each field - saves typing it out manually. Glad you found the explanation helpful! 😊 I'm sure you'll enjoy the book
Tldr on the "how does it do AppState" is generally that it has a FromRequest trait or the like that all parameters to a handler have to implement. I don't know if axum does this, it probably also does proc macro crap so it can get the parameter names...
@@fasterthanlime neat! I think I first saw this trick with an objective C interop library of all things, but it's probably pushed the furthest with Bevy.
How are you liking vscodevim? I heard it's a good gateway into vim itself and after numerous attemps I think I'm finally learning to like it! It seems like the best of both worlds between extensions and the visual side of vs code and the efficiency of vim motions.
Not a separate one, no. It works for SSH remotes and container remotes, so it's either handled by the generic "remote extension" or it's built into it.
What Marie said, plus, since I cover a bunch of low level stuff, it's nicer to interact with a proper kernel in a proper VM, without being stuck in a user namespace.
A tech UA-camr that _ACTUALLY_ programs. Thank god.
I'm going to have to watch this again to fully understand it. But damn, you crushed this video! Great, great work as always Amos!
Other youtubers program too
Hey Tom Scott once used ChatGPT to write some Google Apps Script, I'm fairly sure that qualifies.
Also 1:55, showing us alternate keybinds and unexpected output rather than cutting it. Your rust memory editing dll is the best tutorial I've seen so far
@@fasterthanlime don’t forget his whole the basics series, and the video who’s title updates
Code's here, errata is below: github.com/fasterthanlime/axact
I used an auto-subtitle that transcribed "serde_json" as "Sir De Jason" and I don't know if I'll ever recover.
Correction: the front-end world is not a mess at all I don't know what I was thinking haha don't shun me plz
Correction 2: std::thread::spawn would've been a better choice than tokio::task::spawn_blocking for a background task that never returns.
Correction 3: the next version of Axum will ship #[must_use] on the Websocket's response, which would've caught the "load-bearing semicolon" bug: github.com/tokio-rs/axum/releases/tag/axum-v0.6.10
😅
Doing front end work makes me want to hit my little toe to doors repeatedly.
I think tokio spawn_blocking is at worst the same as std thread spawn? I wouldn't consider it a big deal.
@@SimonBuchanNz tokio has a thread pool and if you never yield, it could end up blocking the entire runtime
@@baggern that's if you use regular spawn. Spawn_blocking is fine.
Dude... the amount of stuff you know... I've been in backend programming for years and have done some js in the past... but man... never in a million years would I be able to jump into the multitude of stuff you just did, especially debugging the websocket issue. Truly impressive.
Love this format of condensing a lot of small concepts into a video, I for one learned a whole lot. Thank you!
Your breadth of knowledge, skill & speed is inspiring! Wild to see you create this in two hours.
So this is a lot more prep work than is visible from the edited version - I spent a half day before that building a way more complicated app! This was shot a couple days after, so it was still fresh in my mind. There were one or two dead-ends while recording where I had to reset, so you know - room for improvement 🧐
Gotta be a lot of work to subtitle all of this. Good shit
I usually hand-subtitle my shorter videos. For this one, UA-cam's auto thing was taking forever so I used github.com/m1guelpf/auto-subtitle which is powered by Whisper and - I'm pleased with the results. ~1.5h of fixing them by hand would have made them perfect (much less work than captioning everything from scratch)
edit: I fixed everything, but it was more like 2.5h 🙃
wow, I actually learned something really valuable from this video: opening the same file in two IDE tabs when it has grown to big vertically
Your coding videos are a breath of fresh air, and amazing content. They include the right amount of “what is he doing here?” to spark immense motivation and curiosity to do this while still being understandable enough to follow. Please do more of these!
You're an excellent coder! Your video is amazing. Many thanks and please continue sharing your knowledge. UA-cam is filled with numerous "programmers," but you stand out as the only one who provides truly informative and practical content. Much appreciation!
Amazing work please keep at it
Damn man, you're so fast and know so much. You inspire me and remind me why I started programming in the first place!
Love this format!
That was a great balance between being authentic (running into issues) without letting the video drag on (cutting to the solution). :)
It was a full hour of enternatiment, thank you for the great content, keep up!
You work at a dizzying pace. I can edit text and commit quickly, but no way my old brain can think this quickly. Respect.
And while talking and explaining....
Packed with good stuff!! I want to see thousands of these
Awesome video! I would love to see a “convert this to production”-video, where you handle errors, make generic views etc. 😊
Seconded, that's a great idea
Learned so much. Unscripted is a vibe! And you're fast
You taught me a lot of things I didn't know in this video. (Even some incidental stuff like the -F/--features flag in cargo add was new to me, too.) Thank you for sharing!
I haven't finished watching this video quite yet, but I just had to say that I genuinely laughed when you discovered that unit implements IntoResponse. That's such a sneaky bit of unexpected behavior!
It's super entertaining watching you code. That speed is insane.
I think he is speeding up the video when he types...
@@Chubbywubbysandwich I also thought that, but if you watch closely, he's not. He's just used to hotkeys
Though I can also code with that speed but, his pace is really insane, I can't react the same as he did, cause if it's me it will take at least a second to process and read the errors/warnings.
@@lighty262 some parts are set at 2x speed (mostly when I don't talk).
19:25 I would just add the "defer" attribute to the script tag so it is fetched in background and run after dom loaded! ;-)
PS: Then the double slash in beginning of fetch. Haha, I am glad I am not the only smart persons doing such mistakes.
This was educative, interesting and impressive! 10/10
Wow, really interesting video, before watching I’d thought that 50 minutes long video will be boring, but I’d been wrong, it was very informative. Hope you will make more videos in this style in the future, I really like it.
Thanks for your efforts!
Great video!
How much of you being so fast is editing, and how much is a genuinely ridiculous typing speed? You have a really efficient workflow, by the looks of it.
When I shut up it's editing, when I talk you can see how fast I really type. I'll do a WPM test on stream one of these days, if that's what the people want.
@@fasterthanlime I think this is more perceptible when editing code then on a WPM test
You not only type fast but you know your hotkeys and combos, so you reach your goal much faster then if you typed everything and the part that you do type is very fast
It is a pretty normal typing speed, idk what you are talking about. What part was ridiculous?
I never thought that I am a power user or anything, but I also use VIM (motions) and WM (awesomewm), not even remotely to the max efficiency, yet I am around the same speed. You guys are much slower?
I think it is around average in our world.
I bet a lot of that speed actually comes from the Vim extension. How he moves through the document still looks like insanity to me though, even as a full time Vim user xD
Even without considering the use of vim keybindings, his typing speed is unbelievable. To prevent bias, try typing directly on a typing measurement site and measure your speed. Even though I feel much slower than the typing speed shown in the video, I still rank in the top 3%
44:00 Finally that "forgot semicolon" is actually true and caused a bug
Really great stuff. I hope there will be more of that content!
29:53 "So how do we get this to center?"
Here you have and example how to center a div in CSS.
This was highly interesting to watch. I’ve recently become interested in Rust, but I mostly work with Go
This almost makes me feel bad for typing not as fast as you do, LOL.
Loved the video. Thank you for all the work!
Really chill video, liked it a lot!
Really cool video, I learned a ton. Thanks!
Awesome video, thanks for making it.
BTW, at least on Linux, when you ask for the CPU usage you essentially get the number of ticks that the CPU was busy/idle (+ some other states) since boot. If you want to give the usage in any given period, you need to know what the ticks were at the beginning and the end, and then subtract one from the other. That's what this library will be doing under the hood somehow. I personally think it makes more sense to have an API that requires you to sample at two points in time and gives the average usage in that interval (or Duration in Rust lingo). Otherwise you're getting something that's making a whole lot of assumptions about how you want to do this sampling.
Yeah that makes a lot of sense and I feel like sysinfo's interface is a bit awkward here!
That was very entertaining and educational. 👍 Thank you. I gotta take a look at your code later as well. 🙂
Thanks for watching!
Awesome Video! Learned quite a lot 🎉
great video, i really enjoyed watching it :)
I was wondering more about your pc setup, do you have a list of hardware/peripheral/apps you use? Workflow feels super smooth and responsive, would be great if you share the info! Thank you
I should probably make a video or article about it because the question keeps coming up. You can check my latest AMA on /r/fasterthanlime (reddit) that has _some_ answers.
@@fasterthanlime God speed to you.
As always, great content, thanks! One question tho, what are you using for window management / resizing?
AltSnap
@@fasterthanlime thanks
I would love an article on how frameworks like axum and actix-web create those handler functions that seem to detect what their parameters are and inject the correct things. It's a technique that may be useful for some other scenarios but I have no clue how it works.
I second that! Without some kind of attribute/decorator, it feels super magical.
Essentially Axum defines a Handler trait which is implemented for functions with certain signatures. It involves a lot of code repetition in the library which is done through macros.
It looks like Axum implements the trait for any function between 0 and 16 compatible parameters. If a function had more than 16 parameters the "magic" would stop and it couldn't be used.
Incredible content ! Didn't see the 50 minutes go by ! ^^ Rust is amazing ! :D You could've done your front in webassembly to have a 99.9% rust stack ;)
babe new hour long Amos vid just dropped
Really helpful! Thank you.
amazing content. the wireshark debugging at 44:00 is impressive, can you make a video longly talking about that?
You're doing a lot of video speed shifts, what software are you using for video editing? We need a clock in the vscode status bar ;)
At first I could not understand what was the goin on with yr windows, then I googled Altdrag, thanks, bro!
I've switched to AltSnap since, it's a fork of AltDrag that's actually maintained!
Do you a list with all your vscode extensions/settings somewhere? It looks really good!
Most important are: rust-analyzer, Error Lens, GitLens. The font is Iosevka, theme is GitHub Dark.
This video was great.. earned you a subscribe for sure..
Just a heads-up about the code around 21:50 where you introduce preact - I'm not so sure preact handles multiple render() calls to the same root in an optimized way. There's nothing in the documentation that describes its behaviour when rendering to an already-rendered-to root, and it's certainly not the intended way to update the page.
It very well may be re-building the whole DOM each time your update() function gets invoked, basically as if you had chosen not to use Preact at all and just generated some HTML in a template string or something. See e.g. preact issue #436 to confirm that this is not an intended use, though it is an old issue. The current documentation mentions a to-be-removed special third argument to render, specifically for replacing an existing root.
editedit: I checked the source as well and it seems that, yep, it just rebuilds the entire Virtual and Browser DOM if you re-invoke render().
Rockstar! Awesome videos!
Awesome video...!!! Coool VSCode Setup what extensions do you have and what editor configs have you applied....ridiculous typing speeeed...Loved it!!!!
I would love to see Cool Bear show up in a video like this.
Everyone would! But... The logistics though
You are very skilled
This was really fun :)
I'd love to read an article on how Bevy & Axum do their queries!
Thank you so much for this informative and well-explained tutorial! 🌟 Your guidance on setting up a Rust backend with real-time WebSocket communication and integrating it with a Preact frontend has been incredibly helpful. I especially appreciated the hands-on examples and clear explanations.
I've subscribed to your channel and liked this video as I found it very valuable and am looking forward to more of your content! 👍
I was wondering if it might be beneficial to explore error handling and reconnection strategies a bit more, particularly for the WebSocket connections. For example, I got 'Error sending message via WebSocket: Error { inner: Io(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }) }' panic error when refreshed the page. Implementing graceful error handling on the Rust side (instead of '.unwrap()' ) and adding automatic reconnection logic in the JavaScript code (not only .onmessage, having .onclose, onerror as well) could further enhance the robustness and user experience of the applications built following your tutorial..?
So that extra semicolon which caused your bug is why I think I'm always going to write "return"
i don't think that would've helped, since it's perfectly ok to explicitly return the empty tuple
@@baggern No the point is if you get in the habit of putting in the "return" it's better. It's way easier to notice a missing "return" than a missing semicolon.
In response to this video the Axum maintainers made the websocket response #[must_use], which would've caught that error!
For the mutex version, would it have made sense to use RwLock instead of a Mutex? Because then multiple requests can have read access at the same time to the CPUs
Probably - I didn't bother because I knew where the video was going and the Mutex wasn't going to live long (nor prosper)
"I can do what I want: this is my video" 😃
At 34:52, i see there is a mutex lock. Is there a scenario where we dont care about the accuracy, for instance, can we simply just read whatever value that is there, and skip the whole locking? Do you have to use a different datatype for this, or does this defeat the purpose of how this setup is intented to be?
I've never seen instant legacy code being written in Rust before. I get it, it's nice for showing concepts and else, but this can't be said to be good code at all. Reminds of the glory days where people were doing tutorials where they store structured data in unstructured data store with their MEAN stack and call it a day.
What extensions do you have installed for vscode? Your setup looks so efficient.
+1 I’d like to know what the theme is too
@fasterthanlime, I wonder if you have hints as what you did to make you feel so comfortable in programming with Rust. I like how you've been able to articulate things rather quickly with effortless familiarity. I'm aiming to achieve similar mastery of the act. What do you suggest that one can do to achieve such?
I wrote in-depth articles about it for about 3 years - worked for me!
thanks for video, need more)
Good one! Thanks!!
I love how fast you are with vscode. Do you have a reason why you use vscode over neovim? and also maybe you can have a keyboard logger on the screen, so that I can look at what shortcuts you are using.
I use vscode for its remote editing feature (this is all happening in a VM). A TUI editor like vim/nvim over SSH isn't the same thing, especially when there's latency involved. Also, the plug-in ecosystem is fantastic and most of the time it just works (VscodeVim has been shaky lately).
@@fasterthanlime thank you for the reply. what service do you use for the VM? that's actually really smart to just have a separate VM for programming because wsl2 takes way too much ram.
What are you using to drag windows in a KDE-like fashion? That is, the resizing the moving with your mouse thing.
That's AltSnap!
How do you change window sizes so fast? is this a keyboard shortcut or like a plugin or something?
I would love to read an article about the axum types
The extractor thingy? Here's the "short" version: docs.rs/axum/0.6.0/axum/handler/trait.Handler.html#implementors
@@fasterthanlime Would really love to hear about long version. I think Bevy (game engine) also does something very similar with their queries.
@@fasterthanlime Yes exactly, thanks! But like ciso said, I'm also interested in the long version, if you have the capacity of course. Great content btw, I always enjoy your videos/blogs.
It's for actix-web rather than axum, but this is a good talk on the pattern:
ua-cam.com/video/7DOYtnCXucw/v-deo.html
i would love to read an article about the axum thingy you talked about
Your workflow is insane! How do you resize and move windows so fast like that? Also, the front-end world do be crazy.
I use a tool called AltDrag: stefansundin.github.io/altdrag/ - it still works on Windows 11, but you have to change some options for HiDPI displays and I need to restart it whenever changing the display config.
KDE has shortcuts for that
Hey Amos, I'm pretty sure the tokio people recommend not putting never ending tasks into a spawn_blocking because it spawns onto a pool and thus you permanently reduce the pool size by 1. Instead they say, just spawn a regular std::thread here
Yup, see pinned comment.
What vsc extension are you using to get warnings and error so look like that?
It's called "Error Lens"
Wow how u type and move so fast on vs code 😮
And it’s fun watching u 😂 ur amazing
I want to learn rust do you have any advice I worked with node and react and I want to jump to something else 😂😂
Maybe java and spring or rust 😅
If loading JS from a file, I think it works easiest just to defer it?
I wonder if this would've been fun to implement with tokio::sync::watch. I feel like this is such a good usecase for something like that. Where one thread can update and send on the channel, and any thread that reads it for an API call can just get the latest value. This uses a better lock I think? I'm not really sure.
Edit: I got to the point in the video where you used the broadcast channel lol
So because there's a fetch / a WebSocket request it might be just getting "lucky" with the DOMContentLoaded thing and we might still need an event listener, I'm not sure. Or maybe modules always run only when the DOM is ready.
watch would be better than broadcast here, I didn't think of it in the heat of the moment!
Do you use Vim keybindings?
you can use cargo-watch
Inspiring!!
At 33:35, we pass different copies of app_state to axum router and to spawn_blocking closure, but changes to the "copy" inside of closure are somehow reflected at the router app_state "copy". Don't know why this works and it confuses me a lot 😕
This is because the AppState struct only has one field, which is an Arc. Arc implements Clone, so because all fields implement Clone Rust can derive the Clone impl for AppState with a macro.
The Clone impl for Arc doesn't create new copies of the data, it just returns an extra reference to the underlying data - Arc being short for "Atomic Reference Count". The Atomic part means the count can be safely updated by multiple threads (it is both Send & Sync) , as opposed to an Rc (just Send I believe), which would be only for a single thread.
Usually that would mean they are all immutable references, as the borrowing rules state that any shared references must be immutable, and only exclusive references can be mutable. This is why the Arc wraps a Mutex - Mutexes are one of the Rust types that use interior mutability. This means you can obtain a mutable reference via an immutable one. Mutexes enforce borrowing rules at runtime by guaranteeing there can only ever be a single mutable reference at any given time. This is achieved via some type system magic where a thread can lock the Mutex, which returns a MutexGuard, and whilst the thread holds that guard it will block other threads from locking it. The guard type is what actually provides the mutable reference, and when it is dropped the Mutex is free to be locked again by another thread.
So basically the Arc means every clone just returns an immutable reference to the same Mutex & underlying data, and the Mutex allows those immutable references to be turned into mutable ones. The data is never copied anywhere. Hopefully that made sense?
If you'd like to learn more, have a look around for resources on "concurrency primitives" - Jon Gjengset has some great videos on Mutexes and other types, there's plenty of blogs around, and the "Rust Atomics and Locks" book by Mara Bos is an excellent resource that explains all the nuts and bolts in a practical way. You can also dig into the standard library's docs for the types & traits mentioned, they do a decent job of outlining things usually!
@@Rozza3 Oh, I didn't realize that traits of struct fields can implicitly affect the struct in that way. That makes sense now.
Thank you for such an elaborate answer. I'll definitely check the "Rust Atomics and Locks" book 🙂
@@JuanDelS Ah, that particular magic is the "[derive(Clone)]" part - only derivable if all struct fields implement Clone, which is true for the Arc in this case. The derived Clone impl will just call .clone() on each field - saves typing it out manually.
Glad you found the explanation helpful! 😊 I'm sure you'll enjoy the book
Wut is that keyboard it sound very cool
Tldr on the "how does it do AppState" is generally that it has a FromRequest trait or the like that all parameters to a handler have to implement. I don't know if axum does this, it probably also does proc macro crap so it can get the parameter names...
That's exactly what Axum does.
@@fasterthanlime neat! I think I first saw this trick with an objective C interop library of all things, but it's probably pushed the furthest with Bevy.
How are you liking vscodevim? I heard it's a good gateway into vim itself and after numerous attemps I think I'm finally learning to like it! It seems like the best of both worlds between extensions and the visual side of vs code and the efficiency of vim motions.
It's been great except for the time they broke undo, and I say this as a vim exile.
@@fasterthanlime That's been a bit of a curveball for me as well. Sometimes `u` straight up doesn't work so I'll resort to ``.
Small question: What rust vscode extensions do you use? I don't have syntax highlighting for variables in format strings with rust-analyzer alone...
Seems like it's theme dependent.
It's a theme setting: code.visualstudio.com/docs/getstarted/themes#_editor-semantic-highlighting
Any chance you can do a Tauri app example that *isn't* yet another todo app which doesn't really do anything actually complex?
Idk, what should the app do?
Is that port forwarding in vscode an extension?
Not a separate one, no. It works for SSH remotes and container remotes, so it's either handled by the generic "remote extension" or it's built into it.
“The frontend world is a mess” well the web frontend world is a mess and truer words have never been spoken.
very cool!!
What remote server do you use? Baremetal? Vps? What provider?
This is just a local VM in VirtualBox. For my online stuff, most of it is on fly.io (I used to work there), the rest is either on AWS or Hetzner.
vscode can use containers for development, seems nicer than VMs
On windows, containers also have to spin up a linux vm to run, so there's not really a difference here. (yes wsl2 is also a vm)
What Marie said, plus, since I cover a bunch of low level stuff, it's nicer to interact with a proper kernel in a proper VM, without being stuck in a user namespace.
great video. what is the font?
It’s Iosevka
Nice nice nice I need to make a tool as well
Whats the name of the window manager hes using?
Windows 11, with AltSnap.
Which font are you using in vscode?
Iosevka
What font do you use
Iosevka
Nice.
Should try it with leptos next time :)
or rust-dominator
For a while I thought your chair headrest was a humongous pair of earphones...
More code adventures with Amos pls
wizard
G R E A T content!