meta pixel

Rust for C# developers: enums


    Posted by Moacir Braga

    on Apr 29th 2025


This article is aimed at developers who already know how to develop software using C#, to show how enums work in Rust, and to explore the alternatives for doing the same things we are used to doing in C#, as well as the new possibilities offered in Rust.

Enums

If you want to learn more about enums, please, read the official documentation.

Simple enums

The main difference is the way we call the enum to use it.

```csharp // C# enum Country { Brazil, England, UnitedStates }

// ... Country country = Country.Brazil; ```

```rust // Rust enum Country { Brazil, England, UnitedStates }

// ... let country: Country = Country::Brazil; ```

Enums with associated fixed values

Almost no difference between C# and Rust.

```csharp // C# enum HttpStatus { OK = 200, NotFound = 404 }

// ... HttpStatus status = HttpStatus.OK; int statusCode = (int)HttpStatus.OK; ```

```rust // Rust enum HttpStatus { OK = 200, NotFound = 404, }

// ... let status: HttpStatus = HttpStatus::OK; let statusCode: i32 = HttpStatus::OK as i32; ```

Enums with custom types

There is no way of doing it directly in an easy and readable way like in C#. The thing is, Rust will use the best size for each enum according to its value.

```csharp // C# enum ErrorCode : ushort { None = 0, ConnectionLost = 100, }

// ... ushort errorCode = (ushort)ErrorCode.None; ```

```rust // Rust enum EnumA { // Each variant has 1 byte A = 1, B = 2 }

enum EnumB { // Each variant has 2 bytes A = 1000, B = 2 }

enum EnumC { // Each variant has 4 bytes A = 100000, B = 2 } ```

Enums as bit flags

There isn't a direct equivalent in Rust, but there are many other alternatives, and one convenient way is importing and using the crate bitflags, which is a macro.

```csharp // C# [Flags] enum WeekDays { None = 0b00000000, // 0 Monday = 0b00000001, // 1 Tuesday = 0b00000010, // 2 Wednesday = 0b00000100, // 4 Thursday = 0b00001000, // 8 Friday = 0b00010000, // 16 Saturday = 0b00100000, // 32 Sunday = 0b01000000, // 64 Weekend = Saturday | Sunday }

// ... WeekDays today = WeekDays.Wednesday; bool isWeekend = today.HasFlag(WeekDays.Weekend); bool isWednesday = today.HasFlag(WeekDays.Wednesday); ```

```rust // Rust use bitflags::bitflags;

bitflags! { struct WeekDays: u8 { const MONDAY = 0b00000001; const TUESDAY = 0b00000010; const WEDNESDAY = 0b00000100; const THURSDAY = 0b00001000; const FRIDAY = 0b00010000; const SATURDAY = 0b00100000; const SUNDAY = 0b01000000; const WEEKEND = Self::SATURDAY.bits | Self::SUNDAY.bits; } }

// ... let today: WeekDays = WeekDays::WEDNESDAY; let isweekend: bool = today.intersects(WeekDays::WEEKEND); let iswednesday: bool = today.contains(WeekDays::WEDNESDAY); ```

Enums with associated unknown values, but known types

There isn't something similar in C#. In Rust, a good approach to work with the associated values of each variant is using the keyword match and impl.

```rust // Rust enum IpAddr { V4(String), V6(String), }

impl IpAddr { fn tostring(&self) -> &String { match self { IpAddr::V4(ip) => ip, IpAddr::V6(ip) => ip, } } fn isipv4(&self) -> bool { match self { IpAddr::V4() => true, IpAddr::V6() => false, } } }

// ... let loopback: IpAddr = IpAddr::V4(String::from("127.0.0.1")); print!("Loopback: {}", loopback.tostring()); println!("Is IPv4? {}", loopback.isipv4()); ```

```rust // Rust enum CanvasCommand { Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), }

impl CanvasCommand { fn apply(&self) { match self { CanvasCommand::Move { x, y } => println!("Move to {}, {}", x, y), CanvasCommand::Write(text) => println!("Write {}", text), CanvasCommand::ChangeColor(r, g, b) => println!("Change color to {}, {}, {}", r, g, b), } } }

// ... let drawing: Vec = vec![ CanvasCommand::Move { x: 10, y: 10 }, CanvasCommand::Write(String::from("Hello")), CanvasCommand::Move { x: 20, y: 20 }, CanvasCommand::Write(String::from("World")), CanvasCommand::ChangeColor(0, 0, 0), ];

for command in drawing { command.apply(); } ```

Moacir BragaTechnology Expert