mop_structs/matrix/dr_matrix/dr_matrix_row_constructor.rs
1use crate::{dim::Dim, prelude::DynDenseStoMut};
2
3/// Constructs a new valid row in a easy and interactive manner.
4///
5/// This struct may panic when out of scope. Please see the `Drop` documentation in
6/// the [`Trait Implementations`](#implementations) section for more information.
7/// #[derive(Debug, PartialEq)]
8#[derive(Debug, PartialEq)]
9pub struct DrMatrixRowConstructor<'a, DS> {
10 data: &'a mut DS,
11 dim: &'a mut Dim<[usize; 2]>,
12 inserted_elems: usize,
13}
14
15impl<'a, DS> DrMatrixRowConstructor<'a, DS>
16where
17 DS: DynDenseStoMut,
18{
19 pub(crate) fn new(data: &'a mut DS, dim: &'a mut Dim<[usize; 2]>) -> Self {
20 DrMatrixRowConstructor {
21 data,
22 dim,
23 inserted_elems: 0,
24 }
25 }
26
27 /// Clones all values of `row` into the current row.
28 ///
29 /// # Examples
30 ///
31 /// ```rust
32 /// use mop_structs::{
33 /// doc_tests::dr_matrix_empty_vec_array,
34 /// matrix::dr_matrix::DrMatrixRef
35 /// };
36 /// let mut a = dr_matrix_empty_vec_array();
37 /// a.row_constructor().copy_values_from_row(&[1, 2, 3, 4, 5]).commit();
38 /// assert_eq!(a.as_ref(), DrMatrixRef::new(
39 /// [1, 5],
40 /// &[1, 2, 3, 4, 5],
41 /// ));
42 /// ```
43 pub fn clone_values_from_row(mut self, row: &[DS::Item]) -> Self
44 where
45 DS::Item: Clone,
46 {
47 self.inserted_elems += row.len();
48 self.data.extend_from_clone(row);
49 self
50 }
51
52 /// Commits the row construction, modifying the internal structure.
53 ///
54 /// # Examples
55 ///
56 /// ```rust
57 /// use mop_structs::{
58 /// doc_tests::dr_matrix_empty_vec_array,
59 /// matrix::dr_matrix::DrMatrixRef
60 /// };
61 /// let mut a = dr_matrix_empty_vec_array();
62 /// a.row_constructor()
63 /// .push_value(1)
64 /// .push_value(2)
65 /// .push_value(3)
66 /// .push_value(4)
67 /// .push_value(5)
68 /// .commit();
69 /// assert_eq!(a.as_ref(), DrMatrixRef::new([1, 5], &[1, 2, 3, 4, 5]));
70 /// ```
71 ///
72 /// # Assertions
73 ///
74 /// * The number of inserted elements must be equal the number of columns of `Self`.
75 ///
76 /// ```should_panic
77 /// use mop_structs::doc_tests::dr_matrix_empty_vec_array;
78 /// let mut a = dr_matrix_empty_vec_array();
79 /// a.row_constructor().push_value(1).commit();
80 /// ```
81 pub fn commit(mut self) {
82 assert!(
83 self.inserted_elems == self.dim.cols(),
84 "The number of inserted elements must be equal the number of columns of `Self`."
85 );
86 self.inserted_elems = 0;
87 *self.dim.rows_mut() += 1;
88 }
89
90 /// Copies all values of `row` into the current row.
91 ///
92 /// # Examples
93 ///
94 /// ```rust
95 /// use mop_structs::{
96 /// doc_tests::dr_matrix_empty_vec_array,
97 /// matrix::dr_matrix::DrMatrixRef
98 /// };
99 /// let mut a = dr_matrix_empty_vec_array();
100 /// a.row_constructor().copy_values_from_row(&[1, 2, 3, 4, 5]).commit();
101 /// assert_eq!(a.as_ref(), DrMatrixRef::new(
102 /// [1, 5],
103 /// &[1, 2, 3, 4, 5],
104 /// ));
105 /// ```
106 pub fn copy_values_from_row(mut self, row: &[DS::Item]) -> Self
107 where
108 DS::Item: Copy,
109 {
110 self.inserted_elems += row.len();
111 self.data.extend(row);
112 self
113 }
114
115 /// Pushes a new value.
116 ///
117 /// # Examples
118 ///
119 /// ```rust
120 /// use mop_structs::{
121 /// doc_tests::{dr_matrix_empty_vec_array, dr_matrix_array},
122 /// };
123 /// let mut a = dr_matrix_empty_vec_array();
124 /// a.row_constructor()
125 /// .push_value(1)
126 /// .push_value(2)
127 /// .push_value(3)
128 /// .push_value(4)
129 /// .push_value(5)
130 /// .commit();
131 /// a.row_constructor()
132 /// .push_value(6)
133 /// .push_value(7)
134 /// .push_value(8)
135 /// .push_value(9)
136 /// .push_value(10)
137 /// .commit();
138 /// a.row_constructor()
139 /// .push_value(11)
140 /// .push_value(12)
141 /// .push_value(13)
142 /// .push_value(14)
143 /// .push_value(15)
144 /// .commit();
145 /// a.row_constructor()
146 /// .push_value(16)
147 /// .push_value(17)
148 /// .push_value(18)
149 /// .push_value(19)
150 /// .push_value(20)
151 /// .commit();
152 /// assert_eq!(a.as_ref(), dr_matrix_array().as_ref());
153 /// ```
154 pub fn push_value(mut self, value: DS::Item) -> Self {
155 self.data.push(value);
156 self.inserted_elems += 1;
157 self
158 }
159}
160
161impl<'a, DS> Drop for DrMatrixRowConstructor<'a, DS> {
162 /// Some measures are taken to ensure a valid format and avoid unexpected runtime behavior.
163 ///
164 /// # Assertions
165 ///
166 /// * Every single nonempty instance of `DrMatrixRowConstructor` must end with a call to
167 /// the `commit` method.
168 ///
169 /// ```should_panic
170 /// use mop_structs::doc_tests::dr_matrix_empty_vec_array;
171 /// let mut a = dr_matrix_empty_vec_array();
172 /// a.row_constructor().push_value(1).push_value(2).push_value(3).push_value(4);
173 /// ```
174 fn drop(&mut self) {
175 if self.inserted_elems > 0 {
176 panic!(
177 "Every single nonempty instance of `DrMatrixRowConstructor` must
178 end with a call to the `commit` method."
179 );
180 }
181 }
182}