I'm going through a book called The Complete Rust Reference Guide, and in the topic on Macros, it presents this exercise:
Write a macro that takes an arbitrary number of elements and outputs an unordered HTML list in a literal string, for instance,
html_list!([1, 2]) => <ul><li>1/<li><li>2</li></ul>
.
My attempt to solve it was as so:
macro_rules! make_list {
($($v:tt),*) => {
{
let mut str_vec = vec!["<ul>"];
$(
str_vec.push(format!("<li>{}</li>", $v));
)*
str_vec.push("</ul>");
str_vec.join("")
}
}
}
I attempt to test it with the following test:
let onetwothree = make_list!(1, 2, 3);
let abc = make_list!("a", "b", "c");
assert_eq!("<ul><li>1</li><li>2</li><li>3</li></ul>", onetwothree);
assert_eq!("<ul><li>a</li><li>b</li><li>c</li></ul>", abc);
I receive the following errors when running the test:
error[E0308]: mismatched types
--> src/lib.rs:30:27
|
30 | let onetwothree = make_list!(1, 2, 3);
| ^^^^^^^^^^^^^^^^^^^ expected `&str`, found struct `std::string::String`
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> src/lib.rs:30:27
|
30 | let onetwothree = make_list!(1, 2, 3);
| ^^^^^^^^^^^^^^^^^^^ expected `&str`, found struct `std::string::String`
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> src/lib.rs:31:19
|
31 | let abc = make_list!("a", "b", "c");
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found struct `std::string::String`
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> src/lib.rs:31:19
|
31 | let abc = make_list!("a", "b", "c");
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found struct `std::string::String`
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> src/lib.rs:31:19
|
31 | let abc = make_list!("a", "b", "c");
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found struct `std::string::String`
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0308`.
error: could not compile `mac_exer`.
I tried adding some to_owned()
and to_string()
and have never gotten the error message to change.
Am I missing something obvious? Also, is there an easier way to debug this?
I realize I am passing the arguments as comma separated values, rather than as a vec
, but I didn't think that would matter.