mutslices/
lib.rs

1#![warn(
2    missing_docs,
3    missing_debug_implementations,
4    missing_copy_implementations,
5    rustdoc::broken_intra_doc_links
6)]
7//! This crate provides the ability to create many mutable slices of a vector.
8//! Slicers are created from an array of ranges.
9//!
10//! # Examples
11//! 
12//! ```
13//! use mutslices::MutSlice;
14//!
15//! let vec = Vec::from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
16//! let mut mut_slice = MutSlice::vec_into(vec);
17//! let ranges = [(0, 5), (5, 10), (10, 15)];
18//! let [one, two, three] = &mut*mut_slice.slices_mut(&ranges) else { panic!(); };
19//!
20//! two.swap(2, 3);
21//! one.iter_mut().for_each(|elem| *elem = *elem * 3);
22//! one[0] = 77;
23//! two[1] = 78;
24//! one.swap_with_slice(two);
25//! two.swap_with_slice(three);
26//! three.swap_with_slice(one);
27//! let vec_from_slice = mut_slice.into_vec();
28//! assert_eq!(vec_from_slice, vec![77, 6, 9, 12, 15, 11, 12, 13, 14, 15, 6, 78, 9, 8, 10]);
29//! ```
30use std::mem::forget;
31use std::slice::from_raw_parts_mut;
32
33/// Structure to store the moved vector.
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub struct MutSlice<T> {
36    vec: Vec<T>,
37}
38
39impl<T> MutSlice<T> {
40    /// Moves the vector into the structure.
41    ///
42    /// # Examples
43    /// 
44    /// ```
45    /// use mutslices::MutSlice;
46    ///
47    /// let vec = vec![10, 20, 30, 40, 50];
48    /// let mut mut_slice = MutSlice::vec_into(vec);
49    /// ```
50    #[inline]
51    pub fn vec_into(mut vec: Vec<T>) -> Self {
52        let (ptr, length, capacity) = (vec.as_mut_ptr(), vec.len(), vec.capacity());
53        forget(vec);
54        Self {
55            vec: unsafe { Vec::from_raw_parts(ptr, length, capacity) },
56        }
57    }
58
59    /// Creates mutable slices.
60    ///
61    /// # Panics
62    ///
63    /// Panic if range out of the vector bounds or
64    /// ranges overlap or
65    /// the end of the range is smaller than the beginning.
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// use mutslices::MutSlice;
71    ///
72    /// let vec = Vec::from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
73    /// let mut mut_slice = MutSlice::vec_into(vec);
74    /// let ranges = [(0, 3), (3, 5), (5, 10)];
75    /// let [ref mut one, ref mut two, ref mut three] = mut_slice.slices_mut(&ranges)[..] else { panic!(); };
76    /// one[0] = 11;
77    /// two[1] = 55;
78    /// three[2] = 88;
79    /// assert_eq!(*one, &vec![11, 2, 3]);
80    /// assert_eq!(*two, &vec![4, 55]);
81    /// assert_eq!(*three, &vec![6, 7, 88, 9, 10]);
82    /// ```
83    #[inline]
84    pub fn slices_mut(&mut self, ranges: &[(usize, usize)]) -> Vec<&mut [T]> {
85        let mut vec = Vec::new();
86        let mut range_end = 0;
87        for range in ranges.iter() {
88            let (start, end) = *range;
89
90            if self.vec.len() < end {
91                panic!("Index out of range!");
92            } else if start < range_end {
93                panic!("Ranges should not overlap.");
94            } else if start >= end {
95                panic!("Range end must be larger ot equal");
96            }
97
98            unsafe {
99                vec.push(from_raw_parts_mut(
100                    self.vec.as_mut_ptr().add(start),
101                    end - start,
102                ))
103            };
104            range_end = end;
105        }
106        vec
107    }
108
109    /// Reconstructs a vector from a structure.
110    ///
111    /// # Examples
112    ///
113    /// ```
114    /// use mutslices::MutSlice;
115    ///
116    /// let vec = Vec::from([0, 8, 0, 9, 2, 0, 2, 3]);
117    /// let mut mut_slice = MutSlice::vec_into(vec);
118    /// let ranges = [(0, 2), (2, 4), (4, 8)];
119    /// let [day, month, year] = &mut mut_slice.slices_mut(&ranges)[..] else { panic!(); };
120    /// day[1] = 1;
121    /// month[1] = 1;
122    /// year[3] = 4;
123    ///
124    /// let rvec = mut_slice.into_vec();
125    /// assert_eq!(rvec, vec![0, 1, 0, 1, 2, 0, 2, 4]);
126    /// ```
127    #[inline]
128    pub fn into_vec(mut self) -> Vec<T> {
129        unsafe {
130            let (ptr, length, capacity) =
131                (self.vec.as_mut_ptr(), self.vec.len(), self.vec.capacity());
132            forget(self.vec);
133            Vec::from_raw_parts(ptr, length, capacity)
134        }
135    }
136}