Skip to content

Commit b4083ff

Browse files
committed
Improve return type of NonEmpty::split
Fixes #60[^issue-60]. As pointed out in #60, splitting a `NonEmpty` that contains a single element can be ambiguous to a `NonEmpty` equivalent to `(x, [x])`. A better representation for this return type is `(&T, &[T], Option<&T>)`. [^issue-60]: #60 Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
1 parent 4b255e7 commit b4083ff

1 file changed

Lines changed: 21 additions & 9 deletions

File tree

src/lib.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ impl<T> NonEmpty<T> {
505505
/// Deconstruct a `NonEmpty` into its first, last, and
506506
/// middle elements, in that order.
507507
///
508-
/// If there is only one element then first == last.
508+
/// If there is only one element then last is `None`.
509509
///
510510
/// # Example Use
511511
///
@@ -514,19 +514,20 @@ impl<T> NonEmpty<T> {
514514
///
515515
/// let mut non_empty = NonEmpty::from((1, vec![2, 3, 4, 5]));
516516
///
517-
/// // Guaranteed to have the last element and the elements
518-
/// // preceding it.
519-
/// assert_eq!(non_empty.split(), (&1, &[2, 3, 4][..], &5));
517+
/// // When there are two or more elements, the last element is represented
518+
/// // as a `Some`. Elements preceding it, except for the first, are returned
519+
/// // in the middle.
520+
/// assert_eq!(non_empty.split(), (&1, &[2, 3, 4][..], Some(&5)));
520521
///
521522
/// let non_empty = NonEmpty::new(1);
522523
///
523-
/// // Guaranteed to have the last element.
524-
/// assert_eq!(non_empty.split(), (&1, &[][..], &1));
524+
/// // The last element is `None` when there's only one element.
525+
/// assert_eq!(non_empty.split(), (&1, &[][..], None));
525526
/// ```
526-
pub fn split(&self) -> (&T, &[T], &T) {
527+
pub fn split(&self) -> (&T, &[T], Option<&T>) {
527528
match self.tail.split_last() {
528-
None => (&self.head, &[], &self.head),
529-
Some((last, middle)) => (&self.head, middle, last),
529+
None => (&self.head, &[], None),
530+
Some((last, middle)) => (&self.head, middle, Some(last)),
530531
}
531532
}
532533

@@ -1263,5 +1264,16 @@ mod tests {
12631264
);
12641265
Ok(())
12651266
}
1267+
1268+
#[test]
1269+
fn test_arbitrary_with_split() -> arbitrary::Result<()> {
1270+
let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8]);
1271+
let ne = NonEmpty::<i32>::arbitrary(&mut u)?;
1272+
let (head, middle, last) = ne.split();
1273+
let mut tail = middle.to_vec();
1274+
tail.extend(last);
1275+
assert_eq!(ne, NonEmpty { head: *head, tail });
1276+
Ok(())
1277+
}
12661278
}
12671279
}

0 commit comments

Comments
 (0)