Enumerations

In C++ an enum is a bunch of labels assigned an int value. i.e. it is basically a bunch of constants with scalar values.

  1. enum HttpResponse {
  2. okay = 200,
  3. not_found = 404,
  4. internal_error = 500,
  5. };

C++11 extends this concept a little, allowing you to declare an enum that uses another kind of integral type, e.g. a char to hold the values.

  1. enum LibraryCode : char {
  2. checked_in = 'I',
  3. checked_out = 'O',
  4. checked_out_late = 'L'
  5. };

In Rust an enum can be a scalar value just like in C++.

  1. enum HttpResponse {
  2. Ok= 200,
  3. NotFound= 404,
  4. InternalError = 500
  5. };

But an enum can also hold actual data so you can convey far more information than a static value could by itself.

  1. enum HttpResponse {
  2. Ok,
  3. NotFound(String),
  4. InternalError(String, String, Vec<u8>)
  5. }

You can also bind functions to the enum:

  1. impl HttpResponse {
  2. pub fn code(&self) => {
  3. match *self {
  4. HttpResponse::Ok => 200,
  5. HttpResponse::NotFound(_) => 404,
  6. HttpResponse::InternalError(_, _, _) => 500,
  7. }
  8. }
  9. }

So we might have a function that makes an http request and returns a response:

  1. fn do_request(url: &str) -> HttpResponse {
  2. if url == "/invalid" {
  3. HttpResponse::NotFound(url.to_string())
  4. }
  5. else {
  6. HttpResponse::Ok
  7. }
  8. }
  9. //...
  10. let result = do_request("/invalid");
  11. if let HttpResponse::NotFound(url) = result {
  12. println!("The url {} could not be found", url);
  13. }

Now our code is able to return a more meaningful response in an enum and the code is able to extract that response to print out useful information.