mop-structs 0.0.10

Low-level structures for MOP
Documentation
use crate::{dim::Dim, prelude::DynDenseStoMut};

/// Constructs a new valid row in a easy and interactive manner.
///
/// This struct may panic when out of scope. Please see the `Drop` documentation in
/// the [`Trait Implementations`](#implementations) section for more information.
/// #[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq)]
pub struct DrMatrixRowConstructor<'a, DS> {
  data: &'a mut DS,
  dim: &'a mut Dim<[usize; 2]>,
  inserted_elems: usize,
}

impl<'a, DS> DrMatrixRowConstructor<'a, DS>
where
  DS: DynDenseStoMut,
{
  pub(crate) fn new(data: &'a mut DS, dim: &'a mut Dim<[usize; 2]>) -> Self {
    DrMatrixRowConstructor {
      data,
      dim,
      inserted_elems: 0,
    }
  }

  /// Clones all values of `row` into the current row.
  ///
  /// # Examples
  ///
  /// ```rust
  /// use mop_structs::{
  ///     doc_tests::dr_matrix_empty_vec_array,
  ///     matrix::dr_matrix::DrMatrixRef
  /// };
  /// let mut a = dr_matrix_empty_vec_array();
  /// a.row_constructor().copy_values_from_row(&[1, 2, 3, 4, 5]).commit();
  /// assert_eq!(a.as_ref(), DrMatrixRef::new(
  ///     [1, 5],
  ///     &[1, 2, 3, 4, 5],
  /// ));
  /// ```
  pub fn clone_values_from_row(mut self, row: &[DS::Item]) -> Self
  where
    DS::Item: Clone,
  {
    self.inserted_elems += row.len();
    self.data.extend_from_clone(row);
    self
  }

  /// Commits the row construction, modifying the internal structure.
  ///
  /// # Examples
  ///
  /// ```rust
  /// use mop_structs::{
  ///     doc_tests::dr_matrix_empty_vec_array,
  ///     matrix::dr_matrix::DrMatrixRef
  /// };
  /// let mut a = dr_matrix_empty_vec_array();
  /// a.row_constructor()
  ///     .push_value(1)
  ///     .push_value(2)
  ///     .push_value(3)
  ///     .push_value(4)
  ///     .push_value(5)
  ///     .commit();
  /// assert_eq!(a.as_ref(), DrMatrixRef::new([1, 5], &[1, 2, 3, 4, 5]));
  /// ```
  ///
  /// # Assertions
  ///
  /// * The number of inserted elements must be equal the number of columns of `Self`.
  ///
  /// ```should_panic
  /// use mop_structs::doc_tests::dr_matrix_empty_vec_array;
  /// let mut a = dr_matrix_empty_vec_array();
  /// a.row_constructor().push_value(1).commit();
  /// ```
  pub fn commit(mut self) {
    assert!(
      self.inserted_elems == self.dim.cols(),
      "The number of inserted elements must be equal the number of columns of `Self`."
    );
    self.inserted_elems = 0;
    *self.dim.rows_mut() += 1;
  }

  /// Copies all values of `row` into the current row.
  ///
  /// # Examples
  ///
  /// ```rust
  /// use mop_structs::{
  ///     doc_tests::dr_matrix_empty_vec_array,
  ///     matrix::dr_matrix::DrMatrixRef
  /// };
  /// let mut a = dr_matrix_empty_vec_array();
  /// a.row_constructor().copy_values_from_row(&[1, 2, 3, 4, 5]).commit();
  /// assert_eq!(a.as_ref(), DrMatrixRef::new(
  ///     [1, 5],
  ///     &[1, 2, 3, 4, 5],
  /// ));
  /// ```
  pub fn copy_values_from_row(mut self, row: &[DS::Item]) -> Self
  where
    DS::Item: Copy,
  {
    self.inserted_elems += row.len();
    self.data.extend(row);
    self
  }

  /// Pushes a new value.
  ///
  /// # Examples
  ///
  /// ```rust
  /// use mop_structs::{
  ///     doc_tests::{dr_matrix_empty_vec_array, dr_matrix_array},
  /// };
  /// let mut a = dr_matrix_empty_vec_array();
  /// a.row_constructor()
  ///     .push_value(1)
  ///     .push_value(2)
  ///     .push_value(3)
  ///     .push_value(4)
  ///     .push_value(5)
  ///     .commit();
  /// a.row_constructor()
  ///     .push_value(6)
  ///     .push_value(7)
  ///     .push_value(8)
  ///     .push_value(9)
  ///     .push_value(10)
  ///     .commit();
  /// a.row_constructor()
  ///     .push_value(11)
  ///     .push_value(12)
  ///     .push_value(13)
  ///     .push_value(14)
  ///     .push_value(15)
  ///     .commit();
  /// a.row_constructor()
  ///     .push_value(16)
  ///     .push_value(17)
  ///     .push_value(18)
  ///     .push_value(19)
  ///     .push_value(20)
  ///     .commit();
  /// assert_eq!(a.as_ref(), dr_matrix_array().as_ref());
  /// ```
  pub fn push_value(mut self, value: DS::Item) -> Self {
    self.data.push(value);
    self.inserted_elems += 1;
    self
  }
}

impl<'a, DS> Drop for DrMatrixRowConstructor<'a, DS> {
  /// Some measures are taken to ensure a valid format and avoid unexpected runtime behavior.
  ///
  /// # Assertions
  ///
  /// * Every single nonempty instance of `DrMatrixRowConstructor` must end with a call to
  /// the `commit` method.
  ///
  /// ```should_panic
  /// use mop_structs::doc_tests::dr_matrix_empty_vec_array;
  /// let mut a = dr_matrix_empty_vec_array();
  /// a.row_constructor().push_value(1).push_value(2).push_value(3).push_value(4);
  /// ```
  fn drop(&mut self) {
    if self.inserted_elems > 0 {
      panic!(
        "Every single nonempty instance of `DrMatrixRowConstructor` must
                end with a call to the `commit` method."
      );
    }
  }
}