summaryrefslogtreecommitdiff
path: root/src/config/evalsto.rs
blob: eae9b2d5e53b3f6707c9e1aa151758f069e008b8 (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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use std::{marker::PhantomData, sync::Arc};

use mlua::{FromLua, IntoLua, Lua, Result, Value};

use crate::lua::ownedfunction::OwnedFunction;

#[derive(Clone, Debug)]
pub enum EvalTo<T, A> {
    Function(Arc<OwnedFunction>, PhantomData<A>),
    Value(T),
}

impl<T, A> EvalTo<T, A> {
    pub fn get<'lua>(&'lua self, args: A, lua: &'lua Lua) -> Result<T>
    where
        T: FromLua<'lua> + Clone,
        A: IntoLua<'lua>,
    {
        match self {
            EvalTo::Function(value, _) => {
                let func = value.get(lua);
                T::from_lua(func.call(args)?, lua)
            }
            EvalTo::Value(value) => Ok(value.clone()),
        }
    }

    pub const fn new(value: T) -> Self {
        Self::Value(value)
    }
}

impl<'lua, T, A> FromLua<'lua> for EvalTo<T, A>
where
    T: FromLua<'lua> + Clone,
    A: IntoLua<'lua>,
{
    fn from_lua(
        value: mlua::prelude::LuaValue<'lua>,
        lua: &'lua mlua::prelude::Lua,
    ) -> Result<Self> {
        if value.is_function() {
            Ok(Self::Function(
                Arc::new(OwnedFunction::new(value, lua)),
                PhantomData,
            ))
        } else {
            Ok(Self::Value(T::from_lua(value, lua)?))
        }
    }
}

impl<'lua, T, A> IntoLua<'lua> for EvalTo<T, A>
where
    T: FromLua<'lua> + Clone + IntoLua<'lua>,
    A: IntoLua<'lua>,
{
    fn into_lua(self, lua: &'lua mlua::prelude::Lua) -> Result<Value<'lua>> {
        match self {
            EvalTo::Function(value, _) => Ok(value.get(lua).into_lua(lua)?),
            EvalTo::Value(value) => value.into_lua(lua),
        }
    }
}

impl<T, A> Default for EvalTo<T, A>
where
    T: Default,
{
    fn default() -> Self {
        Self::Value(T::default())
    }
}