Crates.io | vec-of-enum |
lib.rs | vec-of-enum |
version | 0.1.1 |
created_at | 2025-04-13 01:55:07.166704+00 |
updated_at | 2025-04-13 01:58:26.274348+00 |
description | Helper macros for a Vec of enum values |
homepage | https://github.com/DenisGorbachev/vec-of-enum |
repository | https://github.com/DenisGorbachev/vec-of-enum |
max_upload_size | |
id | 1631423 |
size | 44,954 |
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"));
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"));
The wrapper struct created using the define!
macro:
#[repr(transparent)]
for zero-cost abstractionDeref
and DerefMut
to Vec<T>
for access to all Vec methodsnew()
, push()
, and extend_from()
methodsDefault
, Extend
, IntoIterator
, From<Vec<T>>
, and Into<Vec<T>>
variants = [...]
optionYou 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.
cargo add vec-of-enum
Like the project? ⭐ Star this repo on GitHub!
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.