aboutsummaryrefslogtreecommitdiff
path: root/.config/awesome/quarrel/native/src/lenses/mod.rs
blob: 6eb5b581ea4ff4ba1e6f3f4c4519168a7a779b94 (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
74
75
76
77
78
79
pub mod application;
pub mod calculator;

use mlua::{
    prelude::*,
    LuaSerdeExt,
};
use serde::{Serialize, Deserialize};

#[derive(Deserialize, Serialize, Clone)]
pub struct Entry {
    pub message: String,
    pub exec: Option<(String, bool)>,
}

impl IntoLua for Entry {
    fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
        return lua.to_value(&self)
    }
}

impl FromLua for Entry {
    fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
        return lua.from_value(value);
    }
}

#[derive(Default)]
pub enum Cache {
    Valid(Vec<Entry>),
    #[default]
    Stale
}

pub struct _Lense<T: Lense>(pub T);

pub trait Lense {
    const NAME: &'static str;

    fn set_cache(&mut self, cache: Cache);
    fn get_cache(&self) -> &Cache;

    fn query(lua: &Lua, input: String) -> Result<Vec<Entry>, anyhow::Error>;
}

impl<T: Lense + 'static> LuaUserData for _Lense<T> {
    fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
        // fields.add_field_method_get("cache", |lua, this| {
        //     let cache = this.0.get_cache();
        //     match cache {
        //         Cache::Valid(cache) => Ok(cache.clone().into_lua(lua)?),
        //         Cache::Stale => Ok(LuaNil)
        //     }
        // });

        // fields.add_field_method_set("cache", |_, this, cache: Vec<Entry>| {
        //     Ok(this.0.set_cache(Cache::Valid(cache)))
        // });

        fields.add_field_method_get("stale", |_, this| Ok(matches!(this.0.get_cache(), Cache::Stale)));

        fields.add_field("name", T::NAME);
    }

    fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
        methods.add_method_mut("query", |lua, this, input: String| {
            return Ok(match this.0.get_cache() {
                Cache::Valid(entries) => entries.clone(),
                Cache::Stale => {
                    let entries = T::query(lua, input).map_err(LuaError::external)?;
                    this.0.set_cache(Cache::Valid(entries.clone()));
                    entries
                }
            });
        });

        methods.add_method_mut("mark_stale", |_, this, _: ()| Ok(this.0.set_cache(Cache::Stale)) );
    }
}