summaryrefslogtreecommitdiff
path: root/src/sheet/eval.rs
blob: 2108e4813cd16d555b6928aab8bcbc9d78b9ef23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use std::{
    sync::{Arc, RwLock},
    thread::JoinHandle,
};

use mlua::prelude::*;

use crate::lua;

use super::{cell::Cell, Sheet};

pub trait EvalFunction {
    fn eval_function(
        &self,
        func: String,
        range: Vec<(usize, usize)>,
    ) -> JoinHandle<Result<Sheet, String>>;
}

impl EvalFunction for Arc<RwLock<Sheet>> {
    fn eval_function(
        &self,
        func_text: String,
        range: Vec<(usize, usize)>,
    ) -> JoinHandle<Result<Sheet, String>> {
        *self.read().unwrap().progress.lock().unwrap() = 0;
        let this = Arc::clone(self);
        std::thread::spawn(move || {
            let lua = lua::get();
            let read_sheet = this.read().unwrap();
            let mut sheet = read_sheet.clone();
            let result = lua.load(func_text).eval::<LuaFunction>();

            match result {
                Ok(func) => {
                    let read_sheet = this.read().unwrap();

                    for (i, (row, column)) in range.iter().enumerate() {
                        *read_sheet.progress.lock().unwrap() = (i * 100 / range.len()) as u8;

                        let cellref = read_sheet.get_ref(*row, *column);

                        match func.call::<_, Cell>(cellref) {
                            Ok(cell) => sheet.set_cell(*row, *column, cell),
                            Err(error) => return Err(error.to_string()),
                        }
                    }
                }
                Err(error) => return Err(error.to_string()),
            }

            Ok(sheet)
        })
    }
}