vox_geometry_rust 0.1.2

Geometry Tools for Rust
Documentation
/*
 * // Copyright (c) 2021 Feng Yang
 * //
 * // I am making my contributions/submissions to this project solely in my
 * // personal capacity and am not conveying any rights to any intellectual
 * // property of any third parties.
 */

use std::mem::swap;
use std::slice::IterMut;
use std::ops::{Index, IndexMut};

/// Type with zero element
pub trait ZeroInit: Clone {
    fn zero_init() -> Self;
}

impl ZeroInit for f32 {
    fn zero_init() -> f32 {
        return 0.0;
    }
}

///
/// # 1-D array accessor class.
///
/// This class represents 1-D array accessor. Array accessor provides array-like
/// data read/write functions, but does not handle memory management. Thus, it
/// is more like a random access iterator, but with multi-dimension support.
///
/// - tparam T - Array value type.
///
pub struct Array1<T: ZeroInit> {
    _data: Vec<T>,
}

impl<T: ZeroInit> Array1<T> {
    /// Constructs zero-sized 1-D array.
    /// ```
    /// use vox_geometry_rust::array1::Array1;
    /// let arr: Array1<f32> = Array1::new_default();
    /// assert_eq!(0, arr.size());
    /// ```
    pub fn new_default() -> Array1<T> {
        let vec: Vec<T> = Vec::new();
        return Array1 {
            _data: vec
        };
    }

    /// Constructs 1-D array with given \p size and fill it with \p initVal.
    /// - parameter: size Initial size of the array.
    /// - parameter: initVal Initial value of each array element.
    /// ```
    /// use vox_geometry_rust::array1::Array1;
    /// let arr = Array1::new(9, Some(1.5));
    /// assert_eq!(9, arr.size());
    /// for i in 0..9 {
    ///     assert_eq!(1.5, arr[i]);
    /// }
    /// ```
    pub fn new(size: usize, init_val: Option<T>) -> Array1<T> {
        let mut vec: Vec<T> = Vec::new();
        vec.resize(size, init_val.unwrap_or(T::zero_init()));
        return Array1 {
            _data: vec
        };
    }

    ///
    /// \brief Constructs 1-D array with given initializer list \p lst.
    ///
    /// This constructor will build 1-D array with given initializer list \p lst
    /// such as
    ///
    /// ```
    /// use vox_geometry_rust::array1::Array1;
    /// let arr: Array1<f32> = Array1::new_lst(vec![1.0, 2.0, 4.0, 9.0, 3.0]);
    /// ```
    ///
    /// - parameter: lst Initializer list that should be copy to the new array.
    ///
    /// ```
    /// use vox_geometry_rust::array1::Array1;
    /// let arr = Array1::new_lst(vec![1.0,  2.0,  3.0,  4.0]);
    /// assert_eq!(4, arr.size());
    /// for i in 0..4 {
    ///     assert_eq!(i as f32 + 1.0, arr[i]);
    /// }
    /// ```
    pub fn new_lst(lst: Vec<T>) -> Array1<T> {
        return Array1 {
            _data: lst
        };
    }
}

impl<T: ZeroInit> Array1<T> {
    /// Sets entire array with given \p value.
    /// ```
    /// use vox_geometry_rust::array1::Array1;
    /// let mut arr1 = Array1::new(12, Some(-1.0));
    /// arr1.set_scalar(3.5);
    /// for a in arr1.iter() {
    ///     assert_eq!(3.5, *a);
    /// }
    /// ```
    pub fn set_scalar(&mut self, value: T) {
        for v in &mut self._data {
            *v = value.clone();
        }
    }

    /// Copies given array \p other to this array.
    /// ```
    /// use vox_geometry_rust::array1::Array1;
    /// let mut arr1 = Array1::new(12, Some(-1.0));
    /// arr1.set_self(Array1::new_default());
    /// assert_eq!(0, arr1.size());
    /// ```
    pub fn set_self(&mut self, other: Array1<T>) {
        self._data = other._data.clone();
    }

    /// Copies given initializer list \p lst to this array.
    /// ```
    /// use vox_geometry_rust::array1::Array1;
    /// let mut arr2 = Array1::new(12, Some(-1.0));
    /// arr2.set_lst(vec![2.0, 5.0, 9.0, -1.0]);
    /// assert_eq!(4, arr2.size());
    /// assert_eq!(2.0, arr2[0]);
    /// assert_eq!(5.0, arr2[1]);
    /// assert_eq!(9.0, arr2[2]);
    /// assert_eq!(-1.0, arr2[3]);
    /// ```
    pub fn set_lst(&mut self, lst: Vec<T>) {
        self._data = lst.clone();
    }

    /// Clears the array and resizes to zero.
    /// ```
    /// use vox_geometry_rust::array1::Array1;
    /// let mut arr1 = Array1::new_lst(vec![2.0, 5.0, 9.0, -1.0]);
    /// arr1.clear();
    /// assert_eq!(0, arr1.size());
    /// ```
    pub fn clear(&mut self) {
        self._data.clear();
    }

    /// Resizes the array with \p size and fill the new element with \p initVal.
    /// ```
    /// use vox_geometry_rust::array1::Array1;
    /// let mut arr:Array1<f32>  = Array1::new_default();
    /// arr.resize(9, None);
    /// assert_eq!(9, arr.size());
    /// for i in 0..9 {
    ///     assert_eq!(0.0, arr[i]);
    /// }
    ///
    /// arr.resize(12, Some(4.0));
    /// assert_eq!(12, arr.size());
    /// for i in 0..12 {
    ///     if i < 9 {
    ///         assert_eq!(0.0, arr[i]);
    ///     } else {
    ///         assert_eq!(4.0, arr[i]);
    ///     }
    /// }
    /// ```
    pub fn resize(&mut self, size: usize, init_val: Option<T>) {
        self._data.resize(size, init_val.unwrap_or(T::zero_init()));
    }

    /// Returns the reference to the i-th element.
    pub fn at_mut(&mut self, i: usize) -> &mut T {
        return &mut self._data[i];
    }

    /// Returns the const reference to the i-th element.
    pub fn at(&self, i: usize) -> &T {
        return &self._data[i];
    }

    /// Returns size of the array.
    pub fn size(&self) -> usize {
        return self._data.len();
    }

    /// Swaps the content of the array with \p other array.
    pub fn swap(&mut self, other: &mut Array1<T>) {
        swap(&mut self._data, &mut other._data)
    }

    /// Appends single value \p newVal at the end of the array.
    pub fn push(&mut self, new_val: T) {
        self._data.push(new_val);
    }

    /// Appends \p other array at the end of the array.
    pub fn append(&mut self, other: &mut Array1<T>) {
        self._data.append(&mut other._data);
    }

    /// Returns the iterator of the array.
    /// ```compile_fail
    /// use vox_geometry_rust::array1::Array1;
    /// let mut arr1:Array1<f32> = Array1::new_lst(vec![6.0, 4.0, 1.0, -5.0]);
    /// let mut i:usize = 0;
    /// for elem in arr1.iter_mut() {
    ///     assert_eq!(&mut arr1[i], elem);
    ///     i += 1;
    /// }
    /// ```
    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
        return self._data.iter_mut();
    }

    /// Returns the const iterator of the array.
    /// ```
    /// use vox_geometry_rust::array1::Array1;
    /// let arr1:Array1<f32> = Array1::new_lst(vec![6.0, 4.0, 1.0, -5.0]);
    /// let mut i:usize = 0;
    /// for elem in arr1.iter() {
    ///     assert_eq!(& arr1[i], elem);
    ///     i += 1;
    /// }
    /// ```
    pub fn iter(&self) -> std::slice::Iter<'_, T> {
        return self._data.iter();
    }
}

/// Returns the const reference to i-th element.
impl<T: ZeroInit> Index<usize> for Array1<T> {
    type Output = T;

    fn index(&self, index: usize) -> &Self::Output {
        return &self._data[index];
    }
}

/// Returns the reference to i-th element.
impl<T: ZeroInit> IndexMut<usize> for Array1<T> {
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        return &mut self._data[index];
    }
}