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
|
use super::{
account::session::Session,
error::MyResult,
layout::{DynLayoutPage, LayoutPage},
node::NodeCard,
};
use edit_distance::edit_distance;
use jellybase::database::{DataAcid, ReadableTable, T_NODE, T_USER_NODE};
use rocket::{get, State};
#[get("/search?<query>")]
pub async fn r_search<'a>(
session: Session,
db: &State<DataAcid>,
query: Option<&str>,
) -> MyResult<DynLayoutPage<'a>> {
let results = if let Some(query) = query {
let mut items = {
let txn = db.begin_read()?;
let nodes = txn.open_table(T_NODE)?;
let node_users = txn.open_table(T_USER_NODE)?;
let i = nodes
.iter()?
.map(|a| {
let (x, y) = a.unwrap();
let (x, y) = (x.value().to_owned(), y.value().0);
let z = node_users
.get(&(session.user.name.as_str(), x.as_str()))
.unwrap()
.map(|z| z.value().0)
.unwrap_or_default();
let y = y.public;
(x, y, z)
})
.collect::<Vec<_>>();
drop(nodes);
i
};
let query = query.to_lowercase();
items.sort_by_cached_key(|(_, n, _)| {
n.title
.as_ref()
.map(|x| x.to_lowercase())
.unwrap_or_default()
.split(" ")
.map(|tok| edit_distance(query.as_str(), tok))
.min()
.unwrap_or(usize::MAX)
});
Some(items.into_iter().take(64).collect::<Vec<_>>())
} else {
None
};
Ok(LayoutPage {
title: "Search".to_string(),
class: Some("search"),
content: markup::new! {
h1 { "Search" }
form[action="", method="GET"] {
input[type="text", name="query", placeholder="Search Term"];
input[type="submit", value="Search"];
}
@if let Some(results) = &results {
h2 { "Results" }
ul.children {@for (id, node, udata) in results.iter() {
li { @NodeCard { id, node, udata } }
}}
}
},
})
}
|