Is there an equivalence of the dot syntax for enums of Swift in Rust?

I think the dot syntax for enums of Swift is useful for removing duplicate codes. Does Rust have some sort of syntax sugar as well? Or does it have any plan or even discussions to do so?

As for a Swift example, please see here or below.

enum CompassPoint {
    case north
    case south
    case east
    case west
}
var directionToHead = CompassPoint.west // explicit when declared
directionToHead = .south // inferred when having context
switch directionToHead {
case .north:
    print("Lots of planets have a north")
case .south:
    print("Watch out for penguins")
case .east:
    print("Where the sun rises")
case .west:
    print("Where the skies are blue")
}

As Rust uses :: instead of . to access a value in an enum, I am expecting something like

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

let mut coin = Coin::Nickel;
coin = ::Penny;
match coin {
    ::Penny => 1,
    ::Nickel => 5,
    ::Dime => 10,
    ::Quarter => 25,
};

Is it possible? Or, do the community have some strong reasons not to do so?

Edit: For anyone interested, please see the recent discussion in the internal forum, and to trace back some related and unexpectedly long discussions, please see links posted by others in that discussion.

It requires one more line, but yes you can get a similar experience in Rust:

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

use Coin::*;
let mut coin = Nickel;
coin = Penny;
match coin {
    Penny => 1,
    Nickel => 5,
    Dime => 10,
    Quarter => 25,
};

Note use Coin::* which imports all the symbols from the enum.

It seems to be rather a quick fix, but it's a reasonable one. However, this has side effects I think, as it unnecessarily bring more into the current scope. For example, what if I have a a::b::c::EnumA and a d::e::f::EnumB that have the same enum values with the same names? Or, what if we have a struct called Penny in the current scope? Well, the latter case is OK as I just tested, but in the first case, rustc will complain.

You can use inside a fn or in a {} block, which reduces the scope and the risk for conflicts, but increases the amount of typing. I agree that a shorthand could be beneficial, as in Swift, but I'm not sure Rust really needs it.

Example to reduce scope:

fn a() {
  use Coin::*;
  // Symbols available here
}

2 Likes

Yeah, it's better, but still a quick fix........ It still cannot handle the case where I'd like to use the two conflicting enums in a function, but yeah we can use a {} block as a patch.

I think such a syntax sugar won't compromise the overall rigour and elegance of Rust's syntax, so maybe I can link this to a developer forum post and potentially propose an RFC.

I think the implementation would likely be much more complicated than expected, because match arms are full patterns, and can be much more complex than a single enum value.

Also, I'm pretty sure the syntax ::Item is already reserved for absolute paths.

1 Like

There's some more discussion now on the Internals forum: An equivalence of the dot syntax for enums of Swift in Rust? - language design - Rust Internals

which I opened, unfortunately lol, but thanks!

I think the link was posted mainly so that other readers of this thread are aware of the discussion in the other place. This for example avoids people needing to provide arguments or explanations that have already been given in the other thread.

Really, it probably wouldn't have been the worst idea to post a link to the related internals thread here yourself when opening it. Edit: Just noticing, looks like you've already added it to the first post :+1:

You can employ the full use syntax: use … as local-synonym;
See Providing New Names with the as Keyword in TRPL.

use a::b::c::EnumA as EnumA;
use d::e::f::EnumB as EnumB;

Then call out common_enum_value_K as either EnumA::common_enum_value_K or EnumB::common_enum_value_K.

Notice that common_enum_value_K is not in the current scope; only EnumA and EnumB are.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.