rustonaut / vec1

Rust `Vec<T>` wrapper that gurantees to contain at least 1 element
Apache License 2.0
88 stars 15 forks source link

Feature request: into_only? #29

Closed nyarly closed 6 months ago

nyarly commented 6 months ago

I have a use case where I have a vec1 and it may have exactly one element - in some cases it's an error for there to be more than one element.

Currently I have:

let mut paths = paths_vec1.into_iter();
if let (path, 0) = (paths.next().expect("vec1"), paths.len()) {
    // Exactly one
    Ok(path)
} else {
    // More than one
    Err(BuildError::output(
        "expected exactly one build output, got more".to_string(),
    ))
}

I'd love to have:

fn into_only(self) -> Option<T>

that would consume a vec1 with only one element, but otherwise return None. (Alternatively, it could return a Result with Err(MoreThanOne)). The above would become

if let Some(path) = paths_vec1.into_only() {
    // Exactly one
    Ok(path)
} else {
    // More than one
    Err(BuildError::output(
        "expected exactly one build output, got more".to_string(),
    ))
}

or just

Ok(paths_vec1.into_only().map_err(|e| Err(BuildError::output("..."))?)
rustonaut commented 6 months ago

I'm not sure if it isn't too specific for your use case to be added to the library :thinking: .

I have a bit of time in the two weeks starting next week and plan to update my github projects then. So I will come back to this in 1-2 weeks.

rustonaut commented 6 months ago

I thought about it a bit more but I think it's too specific to your use case/out of scope.

You can always add a simple extension trait like

trait Vec1Ext<T> {
   fn into_only(self) -> Option<T>;
}
impl<T> Vec1Ext<T> for Vec1<T> {
  fn into_only(self) -> Option<T> { 
      ....
  }
}

and then e.g. use crate::utils::Vec1Ext as _