Skip to content

Macros to provide conversions for nested enums

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

n0-computer/nested-enum-utils

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nested enum utils

This crate provides a single attribute macro to provide conversions from enum cases to the enum itself or to some other type.

It only works with enums where each variant has a single unnamed element, and if each variant has a distinct type.

The most basic use is to provide conversions between the enum cases and the enum type itself. You could achieve something similar with the popular derive_more crate.

#[enum_conversions()]
enum Request {
  Get(GetRequest),
  Put(PutRequest),
}

A more advanced use, and the reason for this crate to exist, is to provide conversions between enum variants and any type that itself has a conversion to the enum. This allows to use nested enums, like you would in a complex protocol that has several subsystems.

#[enum_conversions(Request)]
enum StoreRequest {
  Get(GetRequest),
  Put(PutRequest),
}

#[enum_conversions(Request)]
enum NetworkRequest {
  Ping(PingRequest),
}

#[enum_conversions()]
enum Request {
  Store(StoreRequest),
  Network(NetworkRequest),
}

Here we define conversions from GetRequest to StoreRequest, from StoreRequest to Request, and then directly from GetRequest to Request, and corresponding TryFrom conversions in the other direction.

Generated conversions

The generated From conversions are straightforward. Obviously it is always possible to convert from an enum case to the enum itself.

We also generate TryFrom conversions from the enum to each variant, as well as from a reference to the enum to a reference to the variant.

The conversions that take a value are different than the ones from derive_more: they return the unmodified input in the error case, allowing to chain conversion attempts.

let request = ...
match GetRequest::try_from(request) {
  Ok(get) => // handle get request
  Err(request) => {
    // I still got the request and can try something else
    match PutRequest::try_from(request) {
      ...
    }
  }
}

The conversions that take a reference just return a &'static str as the error type. References are Copy, so we can always retry anyway.

About

Macros to provide conversions for nested enums

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages