I was wondering what the consensus, or idiomatic way of designing (non-web) APIs where data is returned that can either be a list of items or a single item of the same type.
For example, assume I have an API method
pub fn foo() -> Vec<Bar>;. More often than not I see an additional method
pub fn foo_single(id: Id) -> Bar; that just returns a single item from the vector based on either a field or a predicate.
With rust and lazy evaluation of iterators I don't really see the point in this because the user could just use
filter. Exception: Filtering does some internal stuff that shouldn't be exposed to the caller.
With the functionality you've described, a caller who just wants one
Bar, but no
- Unnecessary allocation of a
Vec is required
- Unnecessary cloning/copying/generation/whatever of every extra
Bar is required
- The caller also has to do more work too
- Know how to go from
- Do so without any advantages inherent in the original data structure
- Move stuff out of the
Vec and discard the rest
Doing work lazily is still doing work. With a
Vec, you may have an index you can utilize, but that's not iteration.
Imagine a hash map that gave you a
Vec<(&Key, &Value)> instead of being able to get a particular entry. Or without
Vec, still having to iterate over potentially every other entry, comparing keys as you go.
If your list is always going to be a sequence (like
Vec<T>), maybe return
impl Iterator<Item = Bar> instead. That way you let the caller decide if they want to either
collect() into a vector or just
.next().unwrap() for the first element.