use nar_dev_utils::unwrap_or_return;
fn f() -> Option<usize> {
let option = Some(1);
let a = unwrap_or_return!(?option => None); assert_eq!(a, 1);
let option = None;
unwrap_or_return!(?option => Some(0));
unreachable!("因为对None解包提前返回,故此处代码不可达")
}
assert_eq!(f(), Some(0));
fn g(err_default: impl FnOnce(usize) -> usize) -> Result<i32, usize> {
let result = Ok(1);
let a = unwrap_or_return!(@result, x => Err(x)); assert_eq!(a, 1);
let result = Err(2);
unwrap_or_return!(@result, x => Err(err_default(x)));
unreachable!("因为对Err解包提前返回,故此处代码不可达")
}
assert_eq!(g(|x| x + 1), Err(2 + 1));
assert_eq!(g(|x| x - 2), Err(0));
fn h1(x: Option<usize>, default: usize) -> usize {
let result = unwrap_or_return!(?x => default);
result + 1
}
assert_eq!(h1(Some(1), 0), 1 + 1);
assert_eq!(h1(Some(2), 0), 2 + 1);
assert_eq!(h1(None, 0), 0);
assert_eq!(h1(None, 1), 1);
fn h2(counter: &mut usize, x: Option<usize>, y: Result<usize, ()>, z: usize) {
let x = unwrap_or_return!(?x);
*counter += x;
let y = unwrap_or_return!(@y);
*counter += y;
*counter += z;
}
let mut counter = 0;
h2(&mut counter, Some(1), Ok(1), 1); assert_eq!(counter, 3);
h2(&mut counter, Some(1), Ok(1), 0); assert_eq!(counter, 5);
h2(&mut counter, Some(1), Err(()), 1); assert_eq!(counter, 6);
h2(&mut counter, None, Ok(1), 1); assert_eq!(counter, 6);
fn sum_len(vec: impl Into<Vec<usize>>) -> (usize, usize) {
let mut vec = vec.into();
let mut sum = 0;
let mut len = 0;
loop {
sum += unwrap_or_return!(
?vec.pop() => break (sum, len) );
len += 1;
}
}
assert_eq!(sum_len([]), (0, 0));
assert_eq!(sum_len([1, 2, 3]), (6, 3));
assert_eq!(sum_len([1, 1, 1]), (3, 3));
assert_eq!(sum_len([3, 3]), (6, 2));
assert_eq!(sum_len([2, 2, 2]), (6, 3));
fn flat_options_rev(vec: impl Into<Vec<Option<usize>>>) -> Vec<usize> {
let mut vec = vec.into();
let mut result = vec![];
loop {
let option = unwrap_or_return!(?vec.pop() => break result);
let value = unwrap_or_return!(?option => continue);
result.push(value);
}
}
assert_eq!(flat_options_rev([]), []);
assert_eq!(flat_options_rev([Some(1)]), [1]);
assert_eq!(flat_options_rev([Some(1), None]), [1]);
assert_eq!(flat_options_rev([Some(1), None, None]), [1]);
assert_eq!(flat_options_rev([Some(1), None, None, Some(2)]), [2, 1]);
assert_eq!(flat_options_rev([Some(2), None, None, Some(1)]), [1, 2]);
assert_eq!(flat_options_rev([Some(2), None, Some(1), None]), [1, 2]);
assert_eq!(flat_options_rev([Some(2), Some(1), None, None]), [1, 2]);
assert_eq!(flat_options_rev([Some(2), None, Some(1), Some(0)]), [0, 1, 2]);
assert_eq!(flat_options_rev([Some(2), Some(0), None, Some(1)]), [1, 0, 2]);
fn flat_option_pairs<T>(iter: impl IntoIterator<Item = [Option<T>; 2]>) -> Vec<T> {
let mut result = vec![];
for [x, y] in iter {
'x: {
let value = unwrap_or_return!(?x => break 'x ());
result.push(value);
}
'y: {
let value = unwrap_or_return!(?y => break 'y ());
result.push(value);
}
}
result
}
let (s, null) = (Some, None);
assert_eq!(flat_option_pairs::<usize>([]), []);
assert_eq!(flat_option_pairs([[s(1), null]]), [1]);
assert_eq!(flat_option_pairs([[null, s(1)]]), [1]);
assert_eq!(flat_option_pairs([[s(1), null], [null, null]]), [1]);
assert_eq!(flat_option_pairs([[null, s(1)], [null, null]]), [1]);
assert_eq!(flat_option_pairs([[s(1), null], [null, s(2)]]), [1, 2]);
assert_eq!(flat_option_pairs([[s(2), null], [null, s(1)]]), [2, 1]);
assert_eq!(flat_option_pairs([[s(2), null], [s(1), null]]), [2, 1]);
assert_eq!(flat_option_pairs([[s(2), s(1)], [null, null]]), [2, 1]);
assert_eq!(flat_option_pairs([[s(2), null], [s(1), s(0)]]), [2, 1, 0]);
assert_eq!(flat_option_pairs([[s(2), s(0)], [null, s(1)]]), [2, 0, 1]);