Skip to content

DenisGorbachev/vec-of-enum

Repository files navigation

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("[email protected]".into(), "domain is blocked".into())));

// ✅ With `vec-of-enum`: very concise
errors.push(("[email protected]", "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("[email protected]".into(), "domain is blocked".into())));

// ✅ With `vec-of-enum`: very concise
errors.push(("[email protected]", "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.

About

Helper macros for a Vec of enum values

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •