algostru 0.4.0

Algorithms (algo) and Data Structures (stru)
Documentation
use std::{
    io::Stdout,
    rc::Rc,
    cell::RefCell,
    ops::Mul,
    borrow::BorrowMut,
    fmt::Error
};

use tui::{
    backend::CrosstermBackend,
    layout::{Constraint, Direction, Layout},
    Frame,
};

use crate::gui::store::Store;
use crate::gui::screen::Screenable;
use crate::gui::modules::big_o_chart::draw_big_o_chart;

const WINDOW: [(f64, f64); 2] = [
    (0.0, 100.0),
    (0.0, 1000.0)
];
const POINTS: u16 = 200;

pub struct Line {
    pub label: String,
    pub points: Vec<(f64, f64)>,
    y: fn(f64) -> f64
}

impl Line {
    pub fn push(&mut self, x: f64) {
        let y = (self.y)(x);
        if y <= WINDOW[1].1 {
            self.points.push((x, y));
        }
    }
}

pub struct Plot {
    pub lines: Vec<Line>
}

pub struct Dashboard {
    store: Rc<RefCell<Store>>,
    plot: Plot,
}

impl Dashboard {
    pub fn new(store: Rc<RefCell<Store>>) -> Self {
        let x_interval: f64 = WINDOW[0].1 / (POINTS as f64);

        let mut plot = Plot {
            lines: vec![
                Line {
                    label: String::from("O(1)"),
                    points: vec![],
                    y: |_| 1.0
                },
                Line {
                    label: String::from("O(log n)"),
                    points: vec![],
                    y: |x| x.log2()
                },
                Line {
                    label: String::from("O(n)"),
                    points: vec![],
                    y: |x| x
                },
                Line {
                    label: String::from("O(n log n)"),
                    points: vec![],
                    y: |x| x.mul(x.log2())
                },
                Line {
                    label: String::from("O(n^2)"),
                    points: vec![],
                    y: |x| x.powf(2.0)
                },
                Line {
                    label: String::from("O(2^n)"),
                    points: vec![],
                    y: |x| -> f64 {
                        let two: f64 = 2.0;
                        two.powf(x)
                    }
                },
                Line {
                    label: String::from("O(n!)"),
                    points: vec![],
                    y: |x| {
                        fn factorial(x: f64) -> f64 {
                            if x <= 1.0 { return 1.0; }
                            else { return (x) * factorial(x - 1.0); }
                        }
                        factorial(x)
                    }
                },
            ]
        };
        for i in 1..POINTS {
            let x = x_interval.mul(i as f64);
            for line in plot.lines.iter_mut() {
                line.push(x);
            }
        }

        Dashboard {
            store,
            plot,
        }
    }
}

impl Screenable for Dashboard {
    fn draw(&mut self, f: &mut Frame<CrosstermBackend<Stdout>>) -> Result<(), Error> {
        let chunks = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([
                Constraint::Min(0),
            ].as_ref())
            .split(f.size());

        f.render_widget(
            draw_big_o_chart(&WINDOW, self.plot.borrow_mut()),
            chunks[0]
        );

        Ok(())
    }
}