pub trait OrSomeRef<T> {
fn or_some_ref<'a>(self) -> Option<&'a T>
where
Self: 'a;
}
impl<T> OrSomeRef<T> for &T {
#[inline(always)]
fn or_some_ref<'a>(self) -> Option<&'a T>
where
Self: 'a,
{
Some(self)
}
}
impl<T> OrSomeRef<T> for Option<&T> {
#[inline(always)]
fn or_some_ref<'a>(self) -> Option<&'a T>
where
Self: 'a,
{
self
}
}
pub trait OrSomeMut<T>: OrSomeRef<T> {
fn or_some_mut<'a>(self) -> Option<&'a mut T>
where
Self: 'a;
}
impl<T> OrSomeRef<T> for &mut T {
#[inline(always)]
fn or_some_ref<'a>(self) -> Option<&'a T>
where
Self: 'a,
{
Some(self)
}
}
impl<T> OrSomeRef<T> for Option<&mut T> {
#[inline(always)]
fn or_some_ref<'a>(self) -> Option<&'a T>
where
Self: 'a,
{
self.map(|r| &*r)
}
}
impl<T> OrSomeMut<T> for &mut T {
#[inline(always)]
fn or_some_mut<'a>(self) -> Option<&'a mut T>
where
Self: 'a,
{
Some(self)
}
}
impl<T> OrSomeMut<T> for Option<&mut T> {
#[inline(always)]
fn or_some_mut<'a>(self) -> Option<&'a mut T>
where
Self: 'a,
{
self
}
}
#[cfg(test)]
mod tests {
use super::*;
fn get(option_ref: impl OrSomeRef<usize>) -> Option<usize> {
option_ref.or_some_ref().cloned()
}
fn inc(option_mut: impl OrSomeMut<usize>) {
if let Some(p) = option_mut.or_some_mut() {
*p += 1
}
}
#[test]
fn test_ref() {
let mut a = 1_usize;
let null = None::<usize>;
assert_eq!(null, None); assert_eq!(get(&a), Some(1)); assert_eq!(get(&mut a), Some(1)); assert_eq!(get(Some(&a)), Some(1)); assert_eq!(get(Some(&mut a)), Some(1)); }
#[test]
fn test_mut() {
let mut a = 1_usize;
inc(&mut a); assert_eq!(a, 2);
inc(Some(&mut a)); assert_eq!(a, 3);
inc(None); assert_eq!(a, 3);
}
}