I'm not too sure what the traditional name for such a feature would be, so searching for previous discussions has been difficult.
Summary
In OCaml, you can create an expression within the scope of another module, temporarily bringing in all items from that module for a single expression.
(* instead of *)
let x = Foo.bar + Foo.baz;;
(* you can say *)
let x = Foo.(bar + baz);;
If a similar syntax was added to Rust, certain patterns involving bitflags and repeated references to enum variants would become simpler/more concise to read/write.
Motivation
I often find myself creating a temporary scope to bring in all of the variants of an enum, such as:
enum Fruits {
Banana,
Apple,
Orange
}
let my_basket = {
use Fruits::*;
[Banana, Banana, Apple]
};
// instead of
// let my_basket = [
// Fruits::Banana, Fruits::Banana, Fruits::Apple
// ];
However, this pattern introduces a significant amount of visual noise into my code. The creation of a new multiline block implies to me as a reader that there are intermediate computations going on that will result in a single final value. However, there are no intermediate computations here; only an import.
What if there was shorthand for this pattern of a use
followed by an immediate expression? This would result in much more concise code without the implication a multiline block brings.
let my_basket = use Fruits::* in { [Banana, Banana, Apple] }
Currently, working with bitflags from the bitflags
crate is quite verbose. Below is an excerpt from the wgpu
crate's "boids" example:
...
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
...
Although it seems to be an explicit decision from the developers to use the qualified path of the BufferUsages struct for all calls, dropping the crate name does little to reduce the visual redundancy.
With such a shorthand import syntax, we can reduce the excerpt from the boids example to:
...
usage: use wgpu::BufferUsages::* in { VERTEX | STORAGE | COPY_DST },
...
Alternatives
Macro
I've tried writing a macro for such a syntax:
macro_rules! using {
($module:path, $what:expr) => {
{ use $module::*; $what }
}
}
which works well with enums, but is unable to handle the constants produced within the impl
for a struct. This limitations makes it a no-go for any bitflag structs made using the bitflags
crate, whose constant flags are stored in the impl
for the generated bitflag struct.