Async updates and reformatting for new exercise

- Renamed/ordered the directories for macros, clippy, and conversions, shifting them all one up in numerical order to fit async as number 21
- Added the 21_async directories in exercises and solutions
- Added async1.rs in the 21_async directory in exercises and solutions
- Added async to the info.toml in rustlings-macros and reordered the rest of the exercises in there as well
- Created an exercise for async1 and its solution
This commit is contained in:
Polycarbohydrate 2025-03-07 19:49:35 -05:00
parent ae444eb3da
commit 2ec9c0957e
31 changed files with 108 additions and 12 deletions

View file

@ -0,0 +1,16 @@
# Async (Asynchronous Programming)
Asynchronous programming allows a program to perform tasks concurrently
without blocking the main execution thread. It is particularly useful
for I/O-bound operations, such as network requests or file reading,
where waiting for a response can be done in the background.
In Rust, asynchronous functions are defined using the async keyword
and are executed with the help of an asynchronous runtime like tokio.
This approach improves the efficiency and responsiveness of applications
by enabling them to handle multiple tasks simultaneously.
## Further information
- [Asynchronous Programming in Rust](https://doc.rust-lang.org/book/ch17-00-async-await.html)
- [Learn Tokio](https://tokio.rs/tokio/tutorial/)
- [Tokio Documentation](https://docs.rs/tokio/latest/tokio/)

View file

@ -0,0 +1,34 @@
// Modify delayed_hello to return the string "Hello, world!"
// after waiting for 1 second to pass the test and fix the
// compiler error.
use tokio::time::{sleep, Duration};
// TODO: Change the function signature to fix the compiler error
fn delayed_hello() -> String {
// TODO: Return the string "Hello, world!" after waiting for 1 second
// ...
"Hello, world!".to_string()
}
#[tokio::main]
async fn main() {
// You can experiment optionally here
}
#[cfg(test)]
mod tests {
use super::*;
use tokio::time::Duration;
#[tokio::test]
async fn test_delayed_hello() {
let start = std::time::Instant::now();
let result = delayed_hello().await;
let duration = start.elapsed();
assert_eq!(result, "Hello, world!");
assert!(duration >= Duration::from_secs(1));
println!("Test passed!");
}
}

View file

@ -1079,11 +1079,27 @@ original sending end.
Related section in The Book:
https://doc.rust-lang.org/book/ch16-02-message-passing.html"""
# ASYNC
[[exercises]]
name = "async1"
dir = "21_async"
hint = """
Remember what keyword is used to define an asynchronous function. The function
returns a `Future` that can be awaited.
A keyword is used to wait for the result of a `Future`. It can only
be used inside an asyncronous function.
For documentation on 'tokio::sleep', see:
https://docs.rs/tokio/latest/tokio/time/fn.sleep.html"""
# MACROS
[[exercises]]
name = "macros1"
dir = "21_macros"
dir = "22_macros"
test = false
hint = """
When you call a macro, you need to add something special compared to a regular
@ -1091,7 +1107,7 @@ function call."""
[[exercises]]
name = "macros2"
dir = "21_macros"
dir = "22_macros"
test = false
hint = """
Macros don't quite play by the same rules as the rest of Rust, in terms of
@ -1102,7 +1118,7 @@ Unlike other things in Rust, the order of "where you define a macro" versus
[[exercises]]
name = "macros3"
dir = "21_macros"
dir = "22_macros"
test = false
hint = """
In order to use a macro outside of its module, you need to do something
@ -1110,7 +1126,7 @@ special to the module to lift the macro out into its parent."""
[[exercises]]
name = "macros4"
dir = "21_macros"
dir = "22_macros"
test = false
hint = """
You only need to add a single character to make this compile.
@ -1127,7 +1143,7 @@ https://veykril.github.io/tlborm/"""
[[exercises]]
name = "clippy1"
dir = "22_clippy"
dir = "23_clippy"
test = false
strict_clippy = true
hint = """
@ -1144,7 +1160,7 @@ appropriate replacement constant from `std::f32::consts`."""
[[exercises]]
name = "clippy2"
dir = "22_clippy"
dir = "23_clippy"
test = false
strict_clippy = true
hint = """
@ -1157,7 +1173,7 @@ https://doc.rust-lang.org/std/option/#iterating-over-option"""
[[exercises]]
name = "clippy3"
dir = "22_clippy"
dir = "23_clippy"
test = false
strict_clippy = true
hint = "No hints this time!"
@ -1166,20 +1182,20 @@ hint = "No hints this time!"
[[exercises]]
name = "using_as"
dir = "23_conversions"
dir = "24_conversions"
hint = """
Use the `as` operator to cast one of the operands in the last line of the
`average` function into the expected return type."""
[[exercises]]
name = "from_into"
dir = "23_conversions"
dir = "24_conversions"
hint = """
Follow the steps provided right before the `From` implementation."""
[[exercises]]
name = "from_str"
dir = "23_conversions"
dir = "24_conversions"
hint = """
The implementation of `FromStr` should return an `Ok` with a `Person` object,
or an `Err` with an error if the string is not valid.
@ -1196,7 +1212,7 @@ https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reen
[[exercises]]
name = "try_from_into"
dir = "23_conversions"
dir = "24_conversions"
hint = """
Is there an implementation of `TryFrom` in the standard library that can both do
the required integer conversion and check the range of the input?
@ -1206,6 +1222,6 @@ types?"""
[[exercises]]
name = "as_ref_mut"
dir = "23_conversions"
dir = "24_conversions"
hint = """
Add `AsRef<str>` or `AsMut<u32>` as a trait bound to the functions."""

View file

@ -0,0 +1,30 @@
use tokio::time::{sleep, Duration};
// Change the function signature to be async and return a Future
async fn delayed_hello() -> String {
// Wait for 1 second
sleep(Duration::from_secs(1)).await;
"Hello, world!".to_string()
}
#[tokio::main]
async fn main() {
// You can experiment optionally here
}
#[cfg(test)]
mod tests {
use super::*;
use tokio::time::Duration;
#[tokio::test]
async fn test_delayed_hello() {
let start = std::time::Instant::now();
let result = delayed_hello().await;
let duration = start.elapsed();
assert_eq!(result, "Hello, world!");
assert!(duration >= Duration::from_secs(1));
println!("Test passed!");
}
}