1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! # mMut
//!
//! ## MutPair
//!
//! Get mutalbe references to two locations in Collection by key.
//!
//! ```rust
//! use mmut::MutPair;
//!
//! let mut v = vec![1, 2, 3, 4, 5];
//!
//! let (a, b) = v.mut_pair(1, 3).unwrap();
//! *a = 8;
//! *b = 7;
//!
//! assert_eq!(v, vec![1, 8, 3, 7, 5]);
//! ```

/// # MutPair
///
/// Get mutalbe references to two locations in Collection by key.
///
/// ```rust
/// use mmut::MutPair;
///
/// let mut v = vec![1, 2, 3, 4, 5];
/// {
///     let (a, b) = v.mut_pair(1, 3).unwrap();
///     *a = 8;
///     *b = 7;
/// }
/// assert_eq!(v, vec![1, 8, 3, 7, 5]);
/// ```
pub trait MutPair {
    type Key;
    type Ret;
    fn mut_pair(
        &mut self,
        key1: Self::Key,
        key2: Self::Key,
    ) -> Option<(&mut Self::Ret, &mut Self::Ret)>;
}

impl<T> MutPair for [T] {
    type Key = usize;
    type Ret = T;
    fn mut_pair(
        &mut self,
        key1: Self::Key,
        key2: Self::Key,
    ) -> Option<(&mut Self::Ret, &mut Self::Ret)> {
        match (self.get(key1), self.get(key2)) {
            (Some(v1), Some(v2)) => {
                let ptr1 = v1 as *const Self::Ret as *mut Self::Ret;
                let ptr2 = v2 as *const Self::Ret as *mut Self::Ret;

                Some(unsafe { (&mut *ptr1, &mut *ptr2) })
            }
            _ => None,
        }
    }
}

impl<T> MutPair for std::vec::Vec<T> {
    type Key = usize;
    type Ret = T;
    fn mut_pair(
        &mut self,
        key1: Self::Key,
        key2: Self::Key,
    ) -> Option<(&mut Self::Ret, &mut Self::Ret)> {
        match (self.get(key1), self.get(key2)) {
            (Some(v1), Some(v2)) => {
                let ptr1 = v1 as *const Self::Ret as *mut Self::Ret;
                let ptr2 = v2 as *const Self::Ret as *mut Self::Ret;

                Some(unsafe { (&mut *ptr1, &mut *ptr2) })
            }
            _ => None,
        }
    }
}

impl<K: Eq + core::hash::Hash, T> MutPair for std::collections::HashMap<K, T> {
    type Key = K;
    type Ret = T;
    fn mut_pair(
        &mut self,
        key1: Self::Key,
        key2: Self::Key,
    ) -> Option<(&mut Self::Ret, &mut Self::Ret)> {
        match (self.get(&key1), self.get(&key2)) {
            (Some(v1), Some(v2)) => {
                let ptr1 = v1 as *const Self::Ret as *mut Self::Ret;
                let ptr2 = v2 as *const Self::Ret as *mut Self::Ret;

                Some(unsafe { (&mut *ptr1, &mut *ptr2) })
            }
            _ => None,
        }
    }
}

impl<K: Ord + core::hash::Hash, T> MutPair for std::collections::BTreeMap<K, T> {
    type Key = K;
    type Ret = T;
    fn mut_pair(
        &mut self,
        key1: Self::Key,
        key2: Self::Key,
    ) -> Option<(&mut Self::Ret, &mut Self::Ret)> {
        match (self.get(&key1), self.get(&key2)) {
            (Some(v1), Some(v2)) => {
                let ptr1 = v1 as *const Self::Ret as *mut Self::Ret;
                let ptr2 = v2 as *const Self::Ret as *mut Self::Ret;

                Some(unsafe { (&mut *ptr1, &mut *ptr2) })
            }
            _ => None,
        }
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}