Rust Practice
This contains a list of practice problems to learn rust syntax generated by Gemini.
Rust Syntax Drills
Drill 1: The “Contact Manager” (Structs & Impl)
Goal: Practice defining data structures and methods (The Rust “Class” equivalent).
- Define a struct
Userwith fields:username(String),email(String), - [ ] andlogin_count(u64). - Create an
implblock forUser. - Implement
fn new(username: &str, email: &str) -> Self. - Implement
fn display(&self)to print user details. - Implement
fn increment_login(&mut self)to increase the count. - In
main, instantiate a mutable user and call all methods.
Drill 2: The “Atmospheric Sensor” (Enums & Match)
Goal: Practice Rust’s specific Enum syntax and pattern matching.
- Define an enum
Temperaturewith variants:Celsius(f64)andFahrenheit(f64). - Write a function
to_celsius(temp: Temperature) -> f64. - Inside the function, use
matchto handle both variants. - Formula for Fahrenheit to Celsius:
(f - 32.0) * 5.0 / 9.0. - In
main, create one of each variant and print the converted values.
Drill 3: The “Shopping List” (Vectors & Ownership)
Goal: Practice the difference between borrowing (&) and moving ownership.
- In
main, create alet mut list = Vec::new();. - Add three
Stringitems to the list. - Create
fn print_list(val: &Vec<String>)that uses aforloop to print items. - Create
fn consume_list(val: Vec<String>)that prints the length and “drops” the list. - In
main, callprint_list(borrow), thenconsume_list(move). - Try to call
print_listone more time at the end to see the compiler error.
Drill 4: The “Safe Divider” (Result & Error Handling)
Goal: Practice the Result type and the match vs if let syntax.
- Write a function
divide(a: f64, b: f64) -> Result<f64, String>. - Return
Err("Cannot divide by zero".to_string())ifb == 0.0. - In
main, call the function with a valid divisor and usematchto print the result. - Call the function with
0.0and useif let Err(e) = ...to print only the error message. - Practice using the “implicit return” (no semicolon) for the function result.
Rust Intermediate Drills
Drill 5: Random Indexer (External Crates)
- Setup
randcrate inCargo.toml. - Create a
Vecof strings. - Use
gen_range(0..vec.len())to pick a random item. - Practice: Ensure the program doesn’t panic if the Vec is empty.
Drill 6: The Cipher Trait (Traits)
- Define
trait Cipher { fn encrypt(&self, data: &str) -> String; }. - Implement
Cipherfor two different “mock” encryption structs. - Create a function that accepts
&dyn Cipheror&impl Cipher. - Observe how Rust handles “Interface” behavior.
Drill 7: Generic Vault (Generics)
- Define
struct Vault<T>. - Implement
newandgetmethods for the generic type. - Instantiate it with a
Stringand then with au32.
Drill 8: OS Entropy (Crypto-Ready)
- Import
rand::rngs::OsRngandrand::RngCore. - Fill a byte buffer
mut key = [0u8; 16]with random data usingOsRng.fill_bytes(). - Print the buffer as a Hex string.
Drill 9: The “Plugin” System (Dynamic Dispatch)
Practice using dyn and Box to store different types in a single collection.
- Define a trait
Pluginwith two methods:fn name(&self) -> &str;fn run(&self);
- Create a struct
AudioPluginand implementPlugin.nameshould return “Audio”.runshould print “Playing sound…“.
- Create a struct
VideoPluginand implementPlugin.nameshould return “Video”.runshould print “Showing frames…“.
- In
main, create aVec<Box<dyn Plugin>>. - Add one
AudioPluginand oneVideoPluginto the vector.- Hint: Use
Box::new(AudioPlugin).
- Hint: Use
- Loop through the vector and call
.run()on each plugin.
Bonus Challenge:
- Try creating a function
execute_plugin(p: &dyn Plugin)and pass an element from your vector to it. This teaches you how to move from aBox(ownership) to a&dyn(borrow).