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!


This does not work, as rust cannot infer the type of
pathA 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.Right, there may be too many unknowns involved. 🤔