1use serde_json::{json, Map};
2
3pub fn build_gnostr_query(
4 authors: Option<&str>,
5 ids: Option<&str>,
6 limit: Option<i32>,
7 generic: Option<(&str, &str)>,
8 hashtag: Option<&str>,
9 mentions: Option<&str>,
10 references: Option<&str>,
11 kinds: Option<&str>,
12) -> Result<String, Box<dyn std::error::Error>> {
13 let mut filt = Map::new();
14
15 if let Some(authors) = authors {
16 filt.insert(
17 "authors".to_string(),
18 json!(authors.split(',').collect::<Vec<&str>>()),
19 );
20 }
21
22 if let Some(ids) = ids {
23 filt.insert(
24 "ids".to_string(),
25 json!(ids.split(',').collect::<Vec<&str>>()),
26 );
27 }
28
29 if let Some(limit) = limit {
30 filt.insert("limit".to_string(), json!(limit));
31 }
32
33 if let Some((tag, val)) = generic {
34 let tag_with_hash = format!("#{}", tag);
35 filt.insert(tag_with_hash, json!(val.split(',').collect::<Vec<&str>>()));
36 }
37
38 if let Some(hashtag) = hashtag {
39 filt.insert(
40 "#t".to_string(),
41 json!(hashtag.split(',').collect::<Vec<&str>>()),
42 );
43 }
44
45 if let Some(mentions) = mentions {
46 filt.insert(
47 "#p".to_string(),
48 json!(mentions.split(',').collect::<Vec<&str>>()),
49 );
50 }
51
52 if let Some(references) = references {
53 filt.insert(
54 "#e".to_string(),
55 json!(references.split(',').collect::<Vec<&str>>()),
56 );
57 }
58
59 if let Some(kinds) = kinds {
60 let kind_ints: Result<Vec<i64>, _> = kinds.split(',').map(|s| s.parse::<i64>()).collect();
61 match kind_ints {
62 Ok(kind_ints) => {
63 filt.insert("kinds".to_string(), json!(kind_ints));
64 }
65 Err(_) => {
66 return Err("Error parsing kinds. Ensure they are integers.".into());
67 }
68 }
69 }
70
71 let q = json!(["REQ", "gnostr-query", filt]);
72 Ok(serde_json::to_string(&q)?)
73}