summaryrefslogtreecommitdiff
path: root/qml_plugin/src/launcher/duckduckgo.rs
blob: 16c9102875e13af9a3458038ed2b5521849e0271 (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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use cxx_qt::{CxxQtType, Threading};
use cxx_qt_lib::QString;
use std::pin::Pin;
use unwrap_print::PrintableResult;

use crate::{ExclusiveExecutor, web::duckduckgo};

#[cxx_qt::bridge]
mod qobject {
    extern "C++" {
        include!("cxx-qt-lib/qstring.h");
        type QString = cxx_qt_lib::QString;
    }

    extern "RustQt" {
        #[qobject]
        #[qml_element]
        #[qml_singleton]
        #[qproperty(
            bool, ok
        )]
        #[qproperty(
            QString, title
        )]
        #[qproperty(
            QString,
            description_html
        )]
        #[qproperty(
            QString, image
        )]
        type DuckDuckGo = super::DuckDuckGoRs;

        #[qinvokable]
        fn query(self: Pin<&mut DuckDuckGo>, input: QString);

        #[qinvokable]
        fn reset(self: Pin<&mut DuckDuckGo>);
    }

    impl cxx_qt::Threading for DuckDuckGo {}
}

#[derive(Default)]
pub struct QmlDuckDuckGo {
    pub title: QString,
    pub description_html: QString,
    pub image: QString,
}

#[derive(Default)]
pub struct DuckDuckGoRs {
    ok: bool,
    title: QString,
    description_html: QString,
    image: QString,

    executor: ExclusiveExecutor,
}

impl qobject::DuckDuckGo {
    fn query(self: Pin<&mut Self>, input: QString) {
        let qt_thread = self.qt_thread();
        self.rust_mut()
            .executor
            .spawn(
                async move {
                    let qinput = input.to_string();
                    let result: Result<QmlDuckDuckGo, _> = duckduckgo::query(&qinput)
                        .await
                        .map(|r| r.into());
                    // consider just unwrapping since this is in a separate thread and is already
                    // end of life anw
                    _ = qt_thread
                        .queue(
                            move |mut qo| match result {
                                Ok(r) => {
                                    if (r
                                        .title
                                        .to_lower()
                                        == input.to_lower()
                                        || r.title
                                            .is_empty())
                                        && r.description_html
                                            .is_empty()
                                        && r.image
                                            .is_empty()
                                    {
                                        qo.as_mut()
                                            .set_ok(false);
                                    } else {
                                        qo.as_mut()
                                            .set_ok(true);
                                        qo.as_mut()
                                            .set_title(r.title);
                                        qo.as_mut()
                                            .set_description_html(r.description_html);
                                        qo.as_mut()
                                            .set_image(r.image);
                                    }
                                }
                                Err(_) => qo.set_ok(false),
                            },
                        )
                        .unwrap_print();
                },
            );
    }

    fn reset(mut self: Pin<&mut Self>) {
        self.as_mut()
            .set_ok(false);
        self.as_mut()
            .set_title("".into());
        self.as_mut()
            .set_description_html("".into());
        self.as_mut()
            .set_image("".into());
    }
}