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}