use functora_tagged::*;
use rust_decimal_macros::dec;
use std::collections::{
BTreeMap, BTreeSet, HashMap, HashSet, VecDeque,
};
#[derive(Debug)]
struct D;
#[test]
fn test_crude_zero() {
let x = Tagged::<i32, D, FCrude>::zero();
assert_eq!(*x, 0);
let y = Tagged::<f64, D, FCrude>::zero();
assert!((*y - 0.0).abs() < f64::EPSILON);
}
#[test]
fn test_crude_one() {
let x = Tagged::<i32, D, FCrude>::one();
assert_eq!(*x, 1);
let y = Tagged::<f64, D, FCrude>::one();
assert!((*y - 1.0).abs() < f64::EPSILON);
}
#[test]
fn test_positive_one() {
let x = Tagged::<i32, D, FPositive>::one();
assert_eq!(*x, 1);
let y = Tagged::<f64, D, FPositive>::one();
assert!((*y - 1.0).abs() < f64::EPSILON);
assert!(Tagged::<i32, D, FPositive>::new(0).is_err());
assert!(Tagged::<i32, D, FPositive>::new(-1).is_err());
}
#[test]
fn test_non_neg_zero() {
let x = Tagged::<i32, D, FNonNeg>::zero();
assert_eq!(*x, 0);
let y =
Tagged::<rust_decimal::Decimal, D, FNonNeg>::zero();
assert_eq!(*y, dec!(0));
}
#[test]
fn test_non_neg_one() {
let x = Tagged::<i32, D, FNonNeg>::one();
assert_eq!(*x, 1);
let y =
Tagged::<rust_decimal::Decimal, D, FNonNeg>::one();
assert_eq!(*y, dec!(1));
}
type NeVec = Tagged<Vec<i32>, D, FNonEmpty>;
#[test]
fn test_non_empty_first() {
let xs = NeVec::new(vec![10, 20, 30]).unwrap();
assert_eq!(xs.first(), &10);
}
#[test]
fn test_non_empty_last() {
let xs = NeVec::new(vec![10, 20, 30]).unwrap();
assert_eq!(xs.last(), &30);
}
#[test]
fn test_non_empty_min_by_key() {
let xs = NeVec::new(vec![10, 5, 20]).unwrap();
assert_eq!(xs.min_by_key(|&x| x), &5);
}
#[test]
fn test_non_empty_max_by_key() {
let xs = NeVec::new(vec![10, 5, 20]).unwrap();
assert_eq!(xs.max_by_key(|&x| x), &20);
}
#[test]
fn test_non_empty_map() {
let xs = NeVec::new(vec![1, 2, 3]).unwrap();
let ys: Tagged<Vec<i32>, D, FNonEmpty> =
xs.map(|x| x * 2);
assert_eq!(*ys, vec![2, 4, 6]);
}
#[test]
fn test_non_empty_min_max() {
let xs = NeVec::new(vec![10, 5, 20]).unwrap();
assert_eq!(xs.minimum(), &5);
assert_eq!(xs.maximum(), &20);
}
#[test]
fn test_non_empty_min_max_by() {
let xs = NeVec::new(vec![10, 5, 20]).unwrap();
assert_eq!(xs.min_by(Ord::cmp), &5);
assert_eq!(xs.max_by(Ord::cmp), &20);
}
#[test]
fn test_non_empty_reduce() {
let xs = NeVec::new(vec![1, 2, 3, 4]).unwrap();
let sum = xs.reduce(|a, b| a + b);
assert_eq!(sum, 10);
}
#[test]
fn test_non_empty_rev() {
let xs = NeVec::new(vec![1, 2, 3]).unwrap();
let ys: Tagged<Vec<i32>, D, FNonEmpty> = xs.rev();
assert_eq!(*ys, vec![3, 2, 1]);
}
#[test]
fn test_non_empty_sorted() {
let xs = NeVec::new(vec![3, 1, 2]).unwrap();
let ys: Tagged<Vec<i32>, D, FNonEmpty> = xs.sort();
assert_eq!(*ys, vec![1, 2, 3]);
}
#[test]
fn test_non_empty_sorted_by_key() {
let xs = NeVec::new(vec![1, 2, 3]).unwrap();
let ys: Tagged<Vec<i32>, D, FNonEmpty> =
xs.sort_by_key(|x| -x);
assert_eq!(*ys, vec![3, 2, 1]);
}
#[test]
fn test_non_empty_dedup() {
let xs = NeVec::new(vec![1, 1, 2, 2, 3, 1]).unwrap();
let ys: Tagged<Vec<i32>, D, FNonEmpty> = xs.dedup();
assert_eq!(*ys, vec![1, 2, 3, 1]);
}
#[test]
fn test_zero_excl_to_one_excl() {
assert!(
Tagged::<f64, D, FZeroExclToOneExcl>::new(0.5)
.is_ok()
);
assert!(
Tagged::<f64, D, FZeroExclToOneExcl>::new(0.0)
.is_err()
);
assert!(
Tagged::<f64, D, FZeroExclToOneExcl>::new(1.0)
.is_err()
);
assert!(
Tagged::<f64, D, FZeroExclToOneExcl>::new(-0.1)
.is_err()
);
assert!(
Tagged::<f64, D, FZeroExclToOneExcl>::new(1.1)
.is_err()
);
}
#[test]
fn test_zero_incl_to_one_excl() {
assert!(
Tagged::<f64, D, FZeroInclToOneExcl>::new(0.0)
.is_ok()
);
assert!(
Tagged::<f64, D, FZeroInclToOneExcl>::new(0.5)
.is_ok()
);
assert!(
Tagged::<f64, D, FZeroInclToOneExcl>::new(1.0)
.is_err()
);
assert!(
Tagged::<f64, D, FZeroInclToOneExcl>::new(-0.1)
.is_err()
);
assert!(
Tagged::<f64, D, FZeroInclToOneExcl>::new(1.1)
.is_err()
);
}
#[test]
fn test_zero_excl_to_one_incl() {
assert!(
Tagged::<f64, D, FZeroExclToOneIncl>::new(1.0)
.is_ok()
);
assert!(
Tagged::<f64, D, FZeroExclToOneIncl>::new(0.5)
.is_ok()
);
assert!(
Tagged::<f64, D, FZeroExclToOneIncl>::new(0.0)
.is_err()
);
assert!(
Tagged::<f64, D, FZeroExclToOneIncl>::new(-0.1)
.is_err()
);
assert!(
Tagged::<f64, D, FZeroExclToOneIncl>::new(1.1)
.is_err()
);
}
#[test]
fn test_zero_incl_to_one_incl() {
assert!(
Tagged::<f64, D, FZeroInclToOneIncl>::new(0.0)
.is_ok()
);
assert!(
Tagged::<f64, D, FZeroInclToOneIncl>::new(1.0)
.is_ok()
);
assert!(
Tagged::<f64, D, FZeroInclToOneIncl>::new(0.5)
.is_ok()
);
assert!(
Tagged::<f64, D, FZeroInclToOneIncl>::new(-0.1)
.is_err()
);
assert!(
Tagged::<f64, D, FZeroInclToOneIncl>::new(1.1)
.is_err()
);
}
#[test]
fn test_zero_incl_to_one_excl_zero() {
let x = Tagged::<f64, D, FZeroInclToOneExcl>::zero();
assert!((*x - 0.0).abs() < f64::EPSILON);
}
#[test]
fn test_zero_excl_to_one_incl_one() {
let x = Tagged::<f64, D, FZeroExclToOneIncl>::one();
assert!((*x - 1.0).abs() < f64::EPSILON);
}
#[test]
fn test_zero_incl_to_one_incl_zero_one() {
let x = Tagged::<f64, D, FZeroInclToOneIncl>::zero();
assert!((*x - 0.0).abs() < f64::EPSILON);
let y = Tagged::<f64, D, FZeroInclToOneIncl>::one();
assert!((*y - 1.0).abs() < f64::EPSILON);
}
type NeHashMap =
Tagged<HashMap<i32, &'static str>, D, FNonEmpty>;
#[test]
fn test_non_empty_hashmap_first() {
let mut map = HashMap::new();
let _ = map.insert(1, "one");
let _ = map.insert(2, "two");
let _ = map.insert(3, "three");
let xs = NeHashMap::new(map).unwrap();
let first = xs.first();
assert!(*first.0 >= 1 && *first.0 <= 3);
}
#[test]
fn test_non_empty_hashmap_minimum() {
let mut map = HashMap::new();
let _ = map.insert(10, "ten");
let _ = map.insert(5, "five");
let _ = map.insert(20, "twenty");
let xs = NeHashMap::new(map).unwrap();
assert_eq!(*xs.minimum().0, 5);
}
#[test]
fn test_non_empty_hashmap_maximum() {
let mut map = HashMap::new();
let _ = map.insert(10, "ten");
let _ = map.insert(5, "five");
let _ = map.insert(20, "twenty");
let xs = NeHashMap::new(map).unwrap();
assert_eq!(*xs.maximum().0, 20);
}
#[test]
fn test_non_empty_hashmap_min_by() {
let mut map = HashMap::new();
let _ = map.insert(10, "ten");
let _ = map.insert(5, "five");
let _ = map.insert(20, "twenty");
let xs = NeHashMap::new(map).unwrap();
assert_eq!(*xs.min_by(|a, b| a.0.cmp(b.0)).0, 5);
}
#[test]
fn test_non_empty_hashmap_max_by() {
let mut map = HashMap::new();
let _ = map.insert(10, "ten");
let _ = map.insert(5, "five");
let _ = map.insert(20, "twenty");
let xs = NeHashMap::new(map).unwrap();
assert_eq!(*xs.max_by(|a, b| a.0.cmp(b.0)).0, 20);
}
#[test]
fn test_non_empty_hashmap_min_by_key() {
let mut map = HashMap::new();
let _ = map.insert(10, "ten");
let _ = map.insert(5, "five");
let _ = map.insert(20, "twenty");
let xs = NeHashMap::new(map).unwrap();
assert_eq!(*xs.min_by_key(|x| x.0).0, 5);
}
#[test]
fn test_non_empty_hashmap_max_by_key() {
let mut map = HashMap::new();
let _ = map.insert(10, "ten");
let _ = map.insert(5, "five");
let _ = map.insert(20, "twenty");
let xs = NeHashMap::new(map).unwrap();
assert_eq!(*xs.max_by_key(|x| x.0).0, 20);
}
#[test]
fn test_non_empty_hashmap_reduce() {
let mut map = HashMap::new();
let _ = map.insert(1, "one");
let _ = map.insert(2, "two");
let _ = map.insert(3, "three");
let xs = NeHashMap::new(map).unwrap();
let sum = xs.reduce(|acc, x| (acc.0 + x.0, acc.1));
assert_eq!(sum.0, 6);
}
type NeHashSet = Tagged<HashSet<i32>, D, FNonEmpty>;
#[test]
fn test_non_empty_hashset_first() {
let mut set = HashSet::new();
let _ = set.insert(10);
let _ = set.insert(20);
let _ = set.insert(30);
let xs = NeHashSet::new(set).unwrap();
let first = xs.first();
assert!(*first == 10 || *first == 20 || *first == 30);
}
#[test]
fn test_non_empty_hashset_minimum() {
let mut set = HashSet::new();
let _ = set.insert(10);
let _ = set.insert(5);
let _ = set.insert(20);
let xs = NeHashSet::new(set).unwrap();
assert_eq!(xs.minimum(), &5);
}
#[test]
fn test_non_empty_hashset_maximum() {
let mut set = HashSet::new();
let _ = set.insert(10);
let _ = set.insert(5);
let _ = set.insert(20);
let xs = NeHashSet::new(set).unwrap();
assert_eq!(xs.maximum(), &20);
}
#[test]
fn test_non_empty_hashset_min_by() {
let mut set = HashSet::new();
let _ = set.insert(10);
let _ = set.insert(5);
let _ = set.insert(20);
let xs = NeHashSet::new(set).unwrap();
assert_eq!(xs.min_by(Ord::cmp), &5);
}
#[test]
fn test_non_empty_hashset_max_by() {
let mut set = HashSet::new();
let _ = set.insert(10);
let _ = set.insert(5);
let _ = set.insert(20);
let xs = NeHashSet::new(set).unwrap();
assert_eq!(xs.max_by(Ord::cmp), &20);
}
#[test]
fn test_non_empty_hashset_reduce() {
let mut set = HashSet::new();
let _ = set.insert(1);
let _ = set.insert(2);
let _ = set.insert(3);
let _ = set.insert(4);
let xs = NeHashSet::new(set).unwrap();
let sum = xs.reduce(|a, b| a + b);
assert_eq!(sum, 10);
}
type NeBTreeMap =
Tagged<BTreeMap<i32, &'static str>, D, FNonEmpty>;
#[test]
fn test_non_empty_btreenmap_first() {
let mut map = BTreeMap::new();
let _ = map.insert(1, "one");
let _ = map.insert(2, "two");
let _ = map.insert(3, "three");
let xs = NeBTreeMap::new(map).unwrap();
assert_eq!(*xs.first().0, 1);
}
#[test]
fn test_non_empty_btreenmap_last() {
let mut map = BTreeMap::new();
let _ = map.insert(1, "one");
let _ = map.insert(2, "two");
let _ = map.insert(3, "three");
let xs = NeBTreeMap::new(map).unwrap();
assert_eq!(*xs.last().0, 3);
}
#[test]
fn test_non_empty_btreenmap_minimum() {
let mut map = BTreeMap::new();
let _ = map.insert(10, "ten");
let _ = map.insert(5, "five");
let _ = map.insert(20, "twenty");
let xs = NeBTreeMap::new(map).unwrap();
assert_eq!(*xs.minimum().0, 5);
}
#[test]
fn test_non_empty_btreenmap_maximum() {
let mut map = BTreeMap::new();
let _ = map.insert(10, "ten");
let _ = map.insert(5, "five");
let _ = map.insert(20, "twenty");
let xs = NeBTreeMap::new(map).unwrap();
assert_eq!(*xs.maximum().0, 20);
}
#[test]
fn test_non_empty_btreenmap_reduce() {
let mut map = BTreeMap::new();
let _ = map.insert(1, "one");
let _ = map.insert(2, "two");
let _ = map.insert(3, "three");
let xs = NeBTreeMap::new(map).unwrap();
let sum = xs.reduce(|acc, x| (acc.0 + x.0, acc.1));
assert_eq!(sum.0, 6);
}
type NeBTreeSet = Tagged<BTreeSet<i32>, D, FNonEmpty>;
#[test]
fn test_non_empty_btreeset_first() {
let mut set = BTreeSet::new();
let _ = set.insert(10);
let _ = set.insert(20);
let _ = set.insert(30);
let xs = NeBTreeSet::new(set).unwrap();
assert_eq!(xs.first(), &10);
}
#[test]
fn test_non_empty_btreeset_last() {
let mut set = BTreeSet::new();
let _ = set.insert(10);
let _ = set.insert(20);
let _ = set.insert(30);
let xs = NeBTreeSet::new(set).unwrap();
assert_eq!(xs.last(), &30);
}
#[test]
fn test_non_empty_btreeset_minimum() {
let mut set = BTreeSet::new();
let _ = set.insert(10);
let _ = set.insert(5);
let _ = set.insert(20);
let xs = NeBTreeSet::new(set).unwrap();
assert_eq!(xs.minimum(), &5);
}
#[test]
fn test_non_empty_btreeset_maximum() {
let mut set = BTreeSet::new();
let _ = set.insert(10);
let _ = set.insert(5);
let _ = set.insert(20);
let xs = NeBTreeSet::new(set).unwrap();
assert_eq!(xs.maximum(), &20);
}
#[test]
fn test_non_empty_btreeset_reduce() {
let mut set = BTreeSet::new();
let _ = set.insert(1);
let _ = set.insert(2);
let _ = set.insert(3);
let _ = set.insert(4);
let xs = NeBTreeSet::new(set).unwrap();
let sum = xs.reduce(|a, b| a + b);
assert_eq!(sum, 10);
}
type NeVecDeque = Tagged<VecDeque<i32>, D, FNonEmpty>;
#[test]
fn test_non_empty_vecdeque_first() {
let mut dq = VecDeque::new();
dq.push_back(10);
dq.push_back(20);
dq.push_back(30);
let xs = NeVecDeque::new(dq).unwrap();
assert_eq!(xs.first(), &10);
}
#[test]
fn test_non_empty_vecdeque_last() {
let mut dq = VecDeque::new();
dq.push_back(10);
dq.push_back(20);
dq.push_back(30);
let xs = NeVecDeque::new(dq).unwrap();
assert_eq!(xs.last(), &30);
}
#[test]
fn test_non_empty_vecdeque_minimum() {
let mut dq = VecDeque::new();
dq.push_back(10);
dq.push_back(5);
dq.push_back(20);
let xs = NeVecDeque::new(dq).unwrap();
assert_eq!(xs.minimum(), &5);
}
#[test]
fn test_non_empty_vecdeque_maximum() {
let mut dq = VecDeque::new();
dq.push_back(10);
dq.push_back(5);
dq.push_back(20);
let xs = NeVecDeque::new(dq).unwrap();
assert_eq!(xs.maximum(), &20);
}
#[test]
fn test_non_empty_vecdeque_reduce() {
let mut dq = VecDeque::new();
dq.push_back(1);
dq.push_back(2);
dq.push_back(3);
dq.push_back(4);
let xs = NeVecDeque::new(dq).unwrap();
let sum = xs.reduce(|a, b| a + b);
assert_eq!(sum, 10);
}
#[test]
fn test_non_empty_convert_vec_to_hashmap() {
let pairs = NonEmpty::new(vec![
(1, "one"),
(2, "two"),
(3, "three"),
])
.unwrap();
let map: NonEmpty<HashMap<i32, &'static str>> =
pairs.via_iter();
assert_eq!(map.length(), 3);
assert_eq!(map.get(&1), Some(&"one"));
assert_eq!(map.get(&2), Some(&"two"));
assert_eq!(map.get(&3), Some(&"three"));
}
#[test]
fn test_non_empty_convert_vec_to_btreeset() {
let xs = NonEmpty::new(vec![3, 1, 2]).unwrap();
let set: NonEmpty<BTreeSet<i32>> = xs.via_iter();
assert_eq!(set.length(), 3);
assert_eq!(set.first(), &1);
assert_eq!(set.last(), &3);
}
#[test]
fn test_non_empty_convert_hashmap_to_vec() {
let mut map = HashMap::new();
let _ = map.insert(1, "one");
let _ = map.insert(2, "two");
let ne_map = NonEmpty::new(map).unwrap();
let vec: NonEmpty<Vec<(i32, &'static str)>> =
ne_map.via_iter();
assert_eq!(vec.length(), 2);
}
#[test]
fn test_non_empty_convert_preserves_nonempty() {
let xs = NonEmpty::new(vec![1]).unwrap();
let set: NonEmpty<BTreeSet<i32>> = xs.via_iter();
assert_eq!(set.length(), 1);
assert!(set.contains(&1));
}
#[test]
fn test_non_empty_into_identity() {
let xs = NonEmpty::new(vec![1, 2, 3]).unwrap();
let result: NonEmpty<Vec<i32>> = xs.via_into();
assert_eq!(result.length(), 3);
assert_eq!(result.first(), &1);
assert_eq!(result.last(), &3);
}
#[test]
fn test_non_empty_into_preserves_nonempty() {
let xs = NonEmpty::new(vec![42]).unwrap();
let result: NonEmpty<Vec<i32>> = xs.via_into();
assert_eq!(result.length(), 1);
assert_eq!(result.first(), &42);
}
#[test]
fn test_singleton_vec() {
let xs: NeVec = Tagged::singleton(42);
assert_eq!(xs.length(), 1);
assert_eq!(xs.first(), &42);
assert_eq!(xs.last(), &42);
}
#[test]
fn test_singleton_vec_string() {
let xs: Tagged<Vec<String>, D, FNonEmpty> =
Tagged::singleton("hello".to_string());
assert_eq!(xs.length(), 1);
assert_eq!(xs.first(), "hello");
}
#[test]
fn test_singleton_hashset() {
let xs: Tagged<HashSet<i32>, D, FNonEmpty> =
Tagged::singleton(99);
assert_eq!(xs.length(), 1);
assert!(xs.contains(&99));
}
#[test]
fn test_singleton_btreeset() {
let xs: Tagged<BTreeSet<i32>, D, FNonEmpty> =
Tagged::singleton(7);
assert_eq!(xs.length(), 1);
assert_eq!(xs.first(), &7);
}
#[test]
fn test_singleton_vecdeque() {
let xs: Tagged<VecDeque<i32>, D, FNonEmpty> =
Tagged::singleton(55);
assert_eq!(xs.length(), 1);
assert_eq!(xs.first(), &55);
}
#[test]
fn test_singleton_hashmap() {
let xs: Tagged<
HashMap<i32, &'static str>,
D,
FNonEmpty,
> = Tagged::singleton((1, "one"));
assert_eq!(xs.length(), 1);
assert_eq!(xs.get(&1), Some(&"one"));
}
#[test]
fn test_singleton_btreemap() {
let xs: Tagged<
BTreeMap<i32, &'static str>,
D,
FNonEmpty,
> = Tagged::singleton((1, "one"));
assert_eq!(xs.length(), 1);
assert_eq!(xs.first().0, &1);
}
#[test]
fn test_singleton_string() {
let xs: Tagged<String, D, FNonEmpty> =
Tagged::singleton('z');
assert_eq!(xs.length(), 1);
assert_eq!(&*xs, "z");
}
#[test]
fn test_singleton_nonempty_type() {
let xs: NonEmpty<Vec<i32>> = NonEmpty::singleton(10);
assert_eq!(xs.length(), 1);
assert_eq!(xs.first(), &10);
}
#[test]
fn test_extend_vec() {
let xs = NeVec::singleton(1).extend([2, 3]);
assert_eq!(xs.length(), 3);
assert_eq!(xs.first(), &1);
assert_eq!(xs.last(), &3);
}
#[test]
fn test_extend_vec_empty_iter() {
let xs = NeVec::singleton(42).extend::<i32>([]);
assert_eq!(xs.length(), 1);
assert_eq!(xs.first(), &42);
}
#[test]
fn test_extend_vec_string() {
let xs: Tagged<Vec<String>, D, FNonEmpty> =
Tagged::<Vec<String>, D, FNonEmpty>::singleton(
"a".to_string(),
)
.extend(["b".to_string(), "c".to_string()]);
assert_eq!(xs.length(), 3);
assert_eq!(xs.first(), "a");
assert_eq!(xs.last(), "c");
}
#[test]
fn test_extend_hashset() {
let xs: Tagged<HashSet<i32>, D, FNonEmpty> =
Tagged::<HashSet<i32>, D, FNonEmpty>::singleton(1)
.extend([2, 3]);
assert_eq!(xs.length(), 3);
assert!(xs.contains(&1));
assert!(xs.contains(&2));
assert!(xs.contains(&3));
}
#[test]
fn test_extend_btreeset() {
let xs: Tagged<BTreeSet<i32>, D, FNonEmpty> =
Tagged::<BTreeSet<i32>, D, FNonEmpty>::singleton(1)
.extend([3, 2]);
assert_eq!(xs.length(), 3);
assert_eq!(xs.first(), &1);
assert_eq!(xs.last(), &3);
}
#[test]
fn test_extend_vecdeque() {
let xs: Tagged<VecDeque<i32>, D, FNonEmpty> =
Tagged::<VecDeque<i32>, D, FNonEmpty>::singleton(1)
.extend([2, 3]);
assert_eq!(xs.length(), 3);
assert_eq!(xs.first(), &1);
assert_eq!(xs.last(), &3);
}
#[test]
fn test_extend_hashmap() {
let xs: Tagged<HashMap<i32, &'static str>, D, FNonEmpty> =
Tagged::<HashMap<i32, &'static str>, D, FNonEmpty>::singleton((1, "one")).extend([(2, "two"), (3, "three")]);
assert_eq!(xs.length(), 3);
assert_eq!(xs.get(&1), Some(&"one"));
assert_eq!(xs.get(&2), Some(&"two"));
}
#[test]
fn test_extend_btreemap() {
let xs: Tagged<BTreeMap<i32, &'static str>, D, FNonEmpty> =
Tagged::<BTreeMap<i32, &'static str>, D, FNonEmpty>::singleton((1, "one")).extend([(2, "two")]);
assert_eq!(xs.length(), 2);
assert_eq!(xs.first().0, &1);
}
#[test]
fn test_extend_string() {
let xs: Tagged<String, D, FNonEmpty> =
Tagged::<String, D, FNonEmpty>::singleton('a')
.extend(['b', 'c']);
assert_eq!(xs.length(), 3);
assert_eq!(&*xs, "abc");
}
#[test]
fn test_extend_chained() {
let xs =
NeVec::singleton(1).extend([2, 3]).extend([4, 5]);
assert_eq!(xs.length(), 5);
assert_eq!(xs.first(), &1);
assert_eq!(xs.last(), &5);
}