Now that we have an overview of how macros work, let's dive into another macro challenge. When implementing traits for multiple types, you often end up writing very similar code over and over.
In this challenge, you'll create a macro that generates implementations of a trait for multiple types. The goal is to reduce the amount of boilerplate code you need to write.
Your Task
-
Write a macro named
config_default_implthat:- Accepts a type and a default value as arguments.
- Generates the implementation of
ConfigDefaultfor that type.
-
Use the macro to implement the
ConfigDefaulttrait for the following types:ConnectionTimeoutwith a value of30.MaxConnectionswith a value of100.RetryAttemptswith a value of3.PostgresPortwith a value of5432.MySQLPortwith a value of3306.MongoPortwith a value of27017.RedisPortwith a value of6379.
Hints
If you're stuck, feel free to check out the hints below:
<details> <summary>Click here to reveal hints</summary>-
The syntax for a macro that accepts a type and a value is as follows:
macro_rules! config_default_impl {($type:ty, $value:expr) => {// Implementation here};}
← PreviousNext →
pub trait ConfigDefault {fn get_default() -> Self;}// These types need default valuespub struct ConnectionTimeout(pub u64);pub struct MaxConnections(pub u32);pub struct RetryAttempts(pub u8);pub struct PostgresPort(pub u16);pub struct MySQLPort(pub u16);pub struct MongoPort(pub u16);pub struct RedisPort(pub u16);#[macro_export]macro_rules! config_default_impl {// TODO: Implement the macro here}// TODO: Use the macro to implement ConfigDefault for each type// Example usagepub fn main() {// let's say we have a new structstruct CustomPort(pub u16);// we implement the ConfigDefault trait for CustomPortconfig_default_impl!(CustomPort, 8080);// when running the `get_default` method, it should return the default valueassert_eq!(<CustomPort as ConfigDefault>::get_default().0, 8080);}