Hey,
Is there any way to create a macro that allows a Some<T> or T as input?
It’s for creating a Span struct that I’m using:
struct Span {
line: usize,
column: usize,
file_path: Option<String>,
}
…and I have the following macro:
macro_rules! span {
($line:expr, $column:expr) => {
Span {
line: $line,
column: $column
file_path: None,
}
};
($line:expr, $column:expr, $file_path: expr) => {
Span {
line: $line,
column: $column
file_path: Some($file_path.to_string()),
}
};
}
…which allows me to do this:
let foo = span!(1, 1);
let bar = span!(1, 1, "file.txt");
However, sometimes I don’t want to pass in the file path directly but through a variable that is Option<String>. To do this, I always have to match the variable:
let file_path = Some("file.txt");
let foo = match file_path {
Some(file_path) => span!(1, 1, file_path),
None => span!(1, 1),
}
Is there a way which allows me to directly use span!(1, 1, file_path) where file_path could be "file.txt", Some("file.txt") or None?
Thanks in advance!


A generic impl is impossible.
Imagine you want to turn a
Into<String>toSome(val.into())andOption<Into<String>>toval.map(Into::into).Now, what if there is a type
Twhereimpl From <Option<T>> for Stringis implemented?Then we would have a conflict.
If you only need this for
&strandString, then you can add a wrapper typeOptionStringWrapper(Option<String>)and implementFrom<T> for OptionStringWrapperfor all concrete type cases you want to support, and go from there.