Returning list of errors from function

I have 2 structs that hold various data in BTreeMaps: Library and Project.

The Project struct data contains String values that are intended to be keys to maps in the Library struct.

I have a function called validate() that I am using to validate all String keys within the Project struct actually exist in the Library struct. Where I am running into problems is the return type of validate(). Currently I have it returning a Result<(), Vec<LibraryError>> which is less than ideal as it means I always need to allocate a Vec in the body of the function and I have the edge case that I could potentially return a Err(Vec::new()) which doesn't make any sense in the application.

My goal is to return all errors encountered during validation at the end of the function, rather than early returning Err variants. This is because the validation could take a bit of time, and if it errors, it will force the application to close, as I need the BTreeMap lookups to succeed later in the application and I want to present the total list of errors to the user to fix in a batch instead of drip feeding them one error at a time each time the application exits.

I could use NonEmpty instead of Vec but that only solves part of the problem and it seems like it is partially unmaintained.

Ideally, I would love for the string key lookups to be replaced with actual data structures and references within the application but that is far too complex for where I am right now. I tried with Rc<RefCell<>> and that quickly fell apart.

Thanks in advance!

It seems fine to me. You could wrap it in ValidationErrors type that has the errors as a field or a method to return an error type that can still implement the Error trait.

Empty Vec doesn't cost anything.

well you allocate a vec only if you are about to crash so i don't think neither the latency of the alloc nor the memory usage are problems lol

1 Like

Vec::new is not as bad as it may look. It does not allocate memory on the heap before data are pushed so is cheap to use (see its docs).

1 Like

Marking this as the solution for now, as it allayed my worries about vec::new() allocating when I didn't need it to.