2 releases

new 0.1.1 Apr 13, 2025
0.1.0 Apr 13, 2025

#877 in Rust patterns

Apache-2.0 OR MIT

26KB
419 lines

Vec of Enum

Documentation

A helper struct to manage a Vec of enum values. Reduces boilerplate, implements useful traits.

let mut errors = ValidationErrors::default();

// ❌ Without `vec-of-enum`: too verbose
errors.push(ValidationError::InvalidEmail(InvalidEmailError::new("user@example.com".into(), "domain is blocked".into())));

// ✅ With `vec-of-enum`: very concise
errors.push(("user@example.com", "domain is blocked"));

Full example

use derive_more::{Constructor, From};
use serde::{Deserialize, Serialize};

// Define some sample validation error structs
#[derive(Constructor, Serialize, Deserialize)]
pub struct PasswordMinLengthError {
    min_length: usize,
}

#[derive(Constructor, Serialize, Deserialize)]
pub struct InvalidEmailError {
    email: String,
    reason: String,
}

// Define an enum that can contain any validation error
#[derive(From, Serialize, Deserialize)]
pub enum ValidationError {
    PasswordMinLength(PasswordMinLengthError),
    InvalidEmail(InvalidEmailError),
}

// Convenience conversion
impl From<(&str, &str)> for ValidationError {
    fn from((email, reason): (&str, &str)) -> Self {
        Self::InvalidEmail(InvalidEmailError::new(email.into(), reason.into()))
    }
}

// Define a typed vector wrapper for ValidationErrors
vec_of_enum::define!(
    #[derive(Serialize, Deserialize)]
    pub struct ValidationErrors(Vec<ValidationError>);
);

// Define a typed vector wrapper that also automatically converts from variant types
vec_of_enum::define!(
    #[derive(Serialize, Deserialize)]
    pub struct ValidationErrorsWithVariants(Vec<ValidationError>);
    variants = [PasswordMinLengthError, InvalidEmailError];
);

let mut errors = ValidationErrors::default();

// ❌ Without `vec-of-enum`: too verbose
errors.push(ValidationError::InvalidEmail(InvalidEmailError::new("user@example.com".into(), "domain is blocked".into())));

// ✅ With `vec-of-enum`: very concise
errors.push(("user@example.com", "domain is blocked"));

Features

The wrapper struct created using the define! macro:

  • Is #[repr(transparent)] for zero-cost abstraction
  • Implements Deref and DerefMut to Vec<T> for access to all Vec methods
  • Provides new(), push(), and extend_from() methods
  • Implements Default, Extend, IntoIterator, From<Vec<T>>, and Into<Vec<T>>
  • Supports automatic conversions from variant types when using the variants = [...] option

Custom Derives

You can add any derive macros to your struct definition, and they will be applied to the generated struct. For example:

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum MyEnum {}

vec_of_enum::define!(
    #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
    pub struct MyVec(Vec<MyEnum>);
);

This allows you to add any necessary derives that your application requires.

Installation

cargo add vec-of-enum

Gratitude

Like the project? ⭐ Star this repo on GitHub!

License

Apache-2.0 or MIT.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, shall be licensed as above, without any additional terms or conditions.

No runtime deps