#[allow(dead_code)]
pub mod prices {
use std::fmt::Display;
#[repr(C)]
#[derive(Debug)]
pub struct CulcPrices<'a> {
min_height_min_width_price: &'a f64,
min_height_max_width_price: &'a f64,
max_height_min_width_price: &'a f64,
max_height_max_width_price: &'a f64,
min_h: &'a f64,
max_h: &'a f64,
min_w: &'a f64,
max_w: &'a f64,
step_w: &'a f64,
step_h: &'a f64,
dist_w: f64,
dist_h: f64,
cols_steps: i64,
rows_steps: i64,
matrix: Vec<Vec<String>>
}
impl<'a> CulcPrices<'a> {
#[no_mangle]
pub fn new(
min_height_min_width_price: &'a f64,
min_height_max_width_price: &'a f64,
max_height_min_width_price: &'a f64,
max_height_max_width_price: &'a f64,
min_h: &'a f64,
max_h: &'a f64,
min_w: &'a f64,
max_w: &'a f64,
step_w: &'a f64,
step_h: &'a f64,
) -> CulcPrices<'a> {
let dist_w = max_w - min_w;
let dist_h = max_h - min_h;
let cols = (dist_w / step_w).floor();
let rows = (dist_h / step_h).floor();
let cols_steps = (cols as i64) + 1;
let rows_steps = (rows as i64) + 1;
CulcPrices {
min_height_min_width_price,
min_height_max_width_price,
max_height_min_width_price,
max_height_max_width_price,
min_h,
max_h,
min_w,
max_w,
step_w,
step_h,
dist_w,
dist_h,
cols_steps,
rows_steps,
matrix: vec![vec![String::from(""); cols_steps as usize]; rows_steps as usize]
}
}
#[no_mangle]
pub fn culc_prices_table(&mut self, uppend_headers: bool) {
let offset = if uppend_headers == true {
self.matrix = vec![vec![String::from(""); (self.cols_steps + 1) as usize]; (self.rows_steps + 1) as usize];
1
} else { 0 };
let mut row_min_val: f64;
let mut row_max_val: f64;
for row in offset..((self.rows_steps + offset as i64)) {
if row == offset {
row_min_val = *self.min_height_min_width_price;
row_max_val = *self.min_height_max_width_price;
} else {
row_min_val = self.min_height_min_width_price + (((row - offset) as f64) * self.step_h) / self.dist_h * (self.max_height_min_width_price - self.min_height_min_width_price);
row_max_val = self.min_height_max_width_price + (((row - offset) as f64) * self.step_h) / self.dist_h * (self.max_height_max_width_price - self.min_height_max_width_price);
}
for col in offset..((self.cols_steps + offset as i64)) {
let val = &((row_min_val + (((col - offset) as f64) * self.step_w) / self.dist_w * (row_max_val - row_min_val)) as f64);
self.matrix[row as usize][col as usize] = format!("{:5.2}", val);
}
}
if uppend_headers {
for row in 0..((self.rows_steps + offset as i64)) {
for col in 0..((self.cols_steps + offset as i64)) {
if row == 0 && col == 0 {
self.matrix[row as usize][col as usize] = String::from("H/W");
} else if row == 0 && col > 0 {
self.matrix[row as usize][col as usize] = format!("{:5.2}", ((col as f64) + self.min_w) * self.step_w);
} else if row > 0 && col == 0 {
self.matrix[row as usize][col as usize] = format!("{:4.2}", ((row as f64) + self.min_h) * self.step_h);
}
}
}
}
}
#[no_mangle]
pub fn set_val(&mut self, row: usize, col: usize, val: f64) {
if row < self.matrix.len() && col < self.matrix[0].len() {
self.matrix[row][col] = val.to_string();
}
}
#[no_mangle]
pub fn set_matrix(&mut self, matrix: Vec<Vec<String>>) {
self.matrix = matrix;
}
#[no_mangle]
pub fn get_ref(&'a self) -> &'a Vec<Vec<String>> {
&self.matrix
}
#[no_mangle]
pub fn get_ref_mut(&'a mut self) -> &'a mut Vec<Vec<String>> {
&mut self.matrix
}
#[no_mangle]
pub fn clone(&self) -> Vec<Vec<String>> {
self.matrix.clone()
}
}
impl<'a> Display for CulcPrices<'a> {
#[no_mangle]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut comma_separated = String::new();
for row in &self.matrix {
for col in row {
comma_separated.push_str( &format!("{}", &col));
comma_separated.push_str(" ");
}
comma_separated.push_str("\n");
}
write!(f, "{}", comma_separated)
}
}
impl<'a> Drop for CulcPrices<'a> {
#[no_mangle]
fn drop(&mut self) {
drop(self.min_height_min_width_price);
drop(self.min_height_max_width_price);
drop(self.max_height_min_width_price);
drop(self.max_height_max_width_price);
drop(self.min_h);
drop(self.max_h);
drop(self.min_w);
drop(self.max_w);
drop(self.step_w);
drop(self.step_h);
drop(self.dist_w);
drop(self.dist_h);
drop(self.cols_steps);
drop(self.rows_steps);
for row in (0..((self.matrix.len() as i64))).rev() {
for col in (0..((self.matrix[row as usize].len() as i64))).rev() {
self.matrix[row as usize].remove(col as usize);
}
self.matrix.remove(row as usize);
}
drop(&self.matrix);
}
}
}
#[cfg(test)]
mod tests {
use crate::prices::CulcPrices;
#[test]
fn matrix_1_with_headers_no_equals_with_matrix_2_with_headers() {
let min_height_min_width_price = 50.0; let min_height_max_width_price = 60.0; let max_height_min_width_price = 70.0; let max_height_max_width_price = 80.0; let min_h = 1.0;
let max_h = 5.0;
let min_w = 1.0;
let max_w = 4.0;
let step_w = 0.5;
let step_h = 0.5;
let mut prices = CulcPrices::new(
&min_height_min_width_price,
&min_height_max_width_price,
&max_height_min_width_price,
&max_height_max_width_price,
&min_h,
&max_h,
&min_w,
&max_w,
&step_w,
&step_h
);
prices.culc_prices_table(false);
let matrix_without_headers_1 = prices.clone();
prices.culc_prices_table(true);
let matrix_with_headers_1 = prices.clone();
assert_ne!(matrix_without_headers_1, matrix_with_headers_1);
}
#[test]
fn matrix_1_without_headers_equals_with_matrix_2_without_headers() {
let min_height_min_width_price = 50.0; let min_height_max_width_price = 60.0; let max_height_min_width_price = 70.0; let max_height_max_width_price = 80.0; let min_h = 1.0;
let max_h = 5.0;
let min_w = 1.0;
let max_w = 4.0;
let step_w = 0.5;
let step_h = 0.5;
let mut prices = CulcPrices::new(
&min_height_min_width_price,
&min_height_max_width_price,
&max_height_min_width_price,
&max_height_max_width_price,
&min_h,
&max_h,
&min_w,
&max_w,
&step_w,
&step_h
);
prices.culc_prices_table(false);
let matrix_without_headers_1 = prices.clone();
prices.culc_prices_table(false);
let matrix_without_headers_2 = prices.clone();
assert_eq!(matrix_without_headers_1, matrix_without_headers_2);
}
#[test]
fn matrix_1_with_headers_equals_with_matrix_2_with_headers() {
let min_height_min_width_price = 50.0; let min_height_max_width_price = 60.0; let max_height_min_width_price = 70.0; let max_height_max_width_price = 80.0; let min_h = 1.0;
let max_h = 5.0;
let min_w = 1.0;
let max_w = 4.0;
let step_w = 0.5;
let step_h = 0.5;
let mut prices = CulcPrices::new(
&min_height_min_width_price,
&min_height_max_width_price,
&max_height_min_width_price,
&max_height_max_width_price,
&min_h,
&max_h,
&min_w,
&max_w,
&step_w,
&step_h
);
prices.culc_prices_table(true);
let matrix_with_headers_1 = prices.clone();
prices.culc_prices_table(true);
let matrix_with_headers_2 = prices.clone();
assert_eq!(matrix_with_headers_1, matrix_with_headers_2);
}
}