Prevent Breaking Code Changes in Future Releases using `non exhaustive` enums in Rust

Table of contents
Reading Time: 2 minutes

Hello everyone, recently I have come across a feature in Rust, known as non_exhaustive. It was introduced in Rust 1.40.0 . This attribute prevents source code-breaking changes in projects downstream.

enums can be non-exhaustive or exhaustive, depending upon their needs. A non-exhaustive enum indicates that this enum may get new value in the future. By adding #[non_exhaustive] attribute, we can create a non-exhaustive enum which forces downstream crates to use wildcard pattern (_) in the match expression and make it non-exhaustive. Otherwise, we will get the compilation error.

Let’s see with a simple example.

  • Create a project using cargo new and define a rust module movie_genresunder this project.
  • Create a file lib.rs and add an enum for movie genres with #[non_exhaustive] attribute.
#[non_exhaustive]
pub enum Genres {
    Horror,
    Comedy,
    Romance,
}
  • In main Cargo.toml add the dependency.
movie_genres = {version = "0.1.0", path="./movie_genres"}
  • Now import movie_genres in main.rs and start testing.
extern crate movie_genres;
use movie_genres::Genres;

fn main() {
    let genres = Genres::Horror;

    match genres {
        Genres::Horror => println!("Horror Movie!!"),
        Genres::Comedy => println!("Comedy Movie!!"),
        Genres::Romance => println!("Romance Movie!!"),
    }
}
  • Now if we hit cargo run, we will get a compilation error.
  • Now add wildcard arm in match expression.
    match genres {
        Genres::Horror => println!("Horror Movie!!"),
        Genres::Comedy => println!("Comedy Movie!!"),
        Genres::Romance => println!("Romance Movie!!"),
        _ => println!("Other movie category"),
    }
  • Add hit cargo run.

You can find full example here https://github.com/knoldus/non_exhaustive_rust_template.

Thanks for reading the blog. If you want to read more content like this?  Subscribe Rust Times Newsletter and receive insights and latest updates, bi-weekly, straight into your inbox. Subscribe Rust Times Newsletter: https://bit.ly/2Vdlld7 .


Knoldus-blog-footer-image

Written by 

Ayush is the Sr. Lead Consultant @ Knoldus Software LLP. In his 10 years of experience he has become a developer with proven experience in architecting and developing web applications. Ayush has a Masters in Computer Application from U.P. Technical University, Ayush is a strong-willed and self-motivated professional who takes deep care in adhering to quality norms within projects. He is capable of managing challenging projects with remarkable deadline sensitivity without compromising code quality.

3 thoughts on “Prevent Breaking Code Changes in Future Releases using `non exhaustive` enums in Rust2 min read

  1. Be careful about deciding to use this. A compilation error is often much better than a runtime error! Exhaustive enums are the default for a reason.

  2. I see it would be useful for enums generated by bindgen, where handling wildcard is mandatory to prevent panics for unknown values.

Comments are closed.