Variantly
Derive helper methods for enum variants that are familiar from Option
& Result
such as unwrap_or
or and_then
.
Example
Derived Methods
In the naming of all methods described here, replace the {variant_name}
with the snake_case formatted name of the given variant.
Option & Result Conversion
Use the below methods to convert the enum into either an option or result:
pub fn {variant_name}(self) -> Option(...)
If the enum is of the given variant, returns a Some
containing the inner variant value. Otherwise, return None.
Example
let color = HSV;
let option = color.hsv;
assert_eq!;
let color = FromOutOfSpace;
assert_eq!;
Note: Available only for tuple-style variants such as Color::RGB(200, 40, 180), or Color::Grey(10)
pub fn {variant_name}_or<E>(self, err: E) -> Result<(...), E>
If the enum is of the given variant, returns a Result::Ok
containing the inner value. Otherwise, return Result::Err
containing err
.
Example
let color = HSV;
let result = color.hsv_or;
assert_eq!;
let color = FromOutOfSpace;
let result = color.hsv_or;
assert_eq!;
Note: Available only for tuple-style variants such as Color::RGB(200, 40, 180), or Color::Grey(10)
pub fn {variant_name}_or_else<E, F: FnOnce() -> E>(self, f: F) -> Result<(...), E>
If the enum is of the given variant, returns a Result::Ok
containing the inner variant value. Otherwise, calls f
to calculate a Result::Err
.
Example
let color = HSV;
let result = color.hsv_or_else;
assert_eq!;
let color = FromOutOfSpace;
let result = color.hsv_or_else;
assert_eq!;
Note: Available only for tuple-style variants such as Color::RGB(200, 40, 180), or Color::Grey(10)
Accessing Inner Values
Use the below methods to easily access the inner value of a given variant.
pub fn expect_{variant_name}(self, msg: &str) -> (...)
Returns the contained value.
Panics
Panics if the enum is not of the given variant with the custom message msg
.
Example
let color_a = HSV;
let color_b = Grey;
let = color_a.expect_hsv;
assert_eq!;
let grey = color_b.expect_grey;
assert_eq!;
Note: Available only for tuple-style variants such as Color::RGB(200, 40, 180), or Color::Grey(10)
pub fn unwrap_{variant_name}(self) -> (...)
Returns the contained value.
Panics
Panics if the enum is not of the given variant.
Example
let color_a = HSV;
let color_b = Grey;
let = color_a.unwrap_hsv;
assert_eq!;
let grey = color_b.unwrap_grey;
assert_eq!;
Note: Available only for tuple-style variants such as Color::RGB(200, 40, 180), or Color::Grey(10)
pub fn unwrap_or_{variant_name}(self, fallback: (...)) -> (...)
Returns the contained value if the enum is of the given variant, otherwise returns the provided fallback
.
Example
let color_a = HSV;
let color_b = Grey;
let = color_a.unwrap_or_hsv;
assert_eq!;
let color = color_b.unwrap_or_rgb;
assert_eq!;
Note: Available only for tuple-style variants such as Color::RGB(200, 40, 180), or Color::Grey(10)
pub fn unwrap_or_else_{variant_name}<F: FnOnce() -> (...)>(self, f: F) -> (...)
Returns the contained value if the enum is of the given variant, otherwise computes a fallback from f
.
Example
let color_a = HSV;
let color_b = Grey;
let = color_a.unwrap_or_else_hsv;
assert_eq!;
let = color_b.unwrap_or_else_hsv;
assert_eq!;
Note: Available only for tuple-style variants such as Color::RGB(200, 40, 180), or Color::Grey(10)
Testing Variant Type
Use the below methods to test whether a variant is of the given type.
pub fn is_{variant_name}(self) -> bool
Returns true
if the enum is of the given variant.
Example
let color = FromOutOfSpace;
assert!;
Note: Available for all variant types
pub fn is_not_{variant_name}(self) -> bool
Returns true
if the enum is not of the given variant.
Example
let color = HSV;
assert!;
Note: Available for all variant types
Compare & Process Specific Variant
Use the below to process and compare a specific enum variant.
pub fn and_{variant_name}(self, enum_b: GivenEnum) -> GivenEnum
Returns enum_b
if both self and enum_b
are of the given variant. Otherwise returns self
.
Example
let color_a = HSV;
let color_b = HSV;
let and = color_a.and_hsv;
assert_eq!;
Available for all variant types
pub fn and_then_{variant_name}<F: FnOnce((...)) -> (...)>(self, f: F) -> Self
Returns the enum as is if it is not of the given variant, otherwise calls f
with the wrapped value and returns the result.
Example
let color_a = HSV;
let and = color_a.and_then_hsv;
assert_eq!;
Note: Available only for tuple-style variants such as Color::RGB(200, 40, 180), or Color::Grey(10)
pub fn or_{variant_name}(self, enum_b: GivenEnum) -> GivenEnum
Returns self
if it is of the given variant, otherwise returns enum_b
.
Example
let color_a = HSV;
let color_b = RGB;
let or = color_a.or_rgb;
assert_eq!;
Available for all variant types
pub fn or_else_{variant_name}<F: FnOnce() -> (...)>(self, f: F) -> Self {
Returns self
if it is of the given variant, otherwise calls f
and returns the result.
Example
let color = HSV;
let color = color.or_else_rgb;
assert_eq!;
Note: Available only for tuple-style variants such as Color::RGB(200, 40, 180), or Color::Grey(10)
Renaming Methods
The variantly
attribute may be placed on a variant in order to customize the resulting method names. The value set against rename
inside the attribute will be used in place of the snake_cased variant name when constructing derived method names.
let variant = SomeVariantWithALongName;
assert!;
Methods associated with SomeVariantWithALongName
will now be accessible only with the variant_a
suffix, such as .unwrap_or_else_variant_a()
. This can help control overly verbose fn names.
Note that the input to rename
is used as is and is not coerced into snake_case.
The above is also relevant when two variant names would expand to create conflicting method names:
Without the rename
attribute in the above, both variants would create conflicting functions such as .is_abc()
due to the coercion to snake_case.
This is avoided by using the rename input to create meaningful and unique fn names.