Skip to content

Commit 2245f9f

Browse files
feat(search): add filtering by post type
1 parent 1ac8e84 commit 2245f9f

4 files changed

Lines changed: 45 additions & 3 deletions

File tree

src/post.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ impl From<String> for ContentType {
2626
}
2727
}
2828

29+
impl Into<String> for ContentType {
30+
fn into(self) -> String {
31+
match self {
32+
ContentType::Post => "post".into(),
33+
ContentType::Link => "link".into(),
34+
ContentType::Quote => "quote".into(),
35+
}
36+
}
37+
}
38+
2939
#[derive(Debug, Clone, Serialize)]
3040
pub struct Post {
3141
pub id: String,

src/services/post.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl PostService {
129129
rusqlite::Error::QueryReturnedNoRows => {
130130
anyhow::anyhow!("Post not found: {}", id_for_error)
131131
}
132-
_ => e.into()
132+
_ => e.into(),
133133
}
134134
} else {
135135
e
@@ -160,7 +160,7 @@ impl PostService {
160160
rusqlite::Error::QueryReturnedNoRows => {
161161
anyhow::anyhow!("Special page not found: {}", id_for_error)
162162
}
163-
_ => e.into()
163+
_ => e.into(),
164164
}
165165
} else {
166166
e

src/services/search.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ impl SearchService {
3131
tags: query.tags.clone(),
3232
from_date: query.from_date.clone(),
3333
to_date: query.to_date.clone(),
34+
post_type: Default::default(),
3435
};
36+
let post_types_as_strings: Vec<String> = query
37+
.post_type
38+
.iter()
39+
.map(|pt| pt.to_owned().into())
40+
.collect();
3541
let offset = (page - 1) * per_page;
3642
let pool = self.pool.clone();
3743

@@ -52,7 +58,9 @@ impl SearchService {
5258
}
5359

5460
for tag in &owned_query.tags {
55-
conditions.push("EXISTS (SELECT 1 FROM json_each(posts.tags) WHERE value = ?)".to_string());
61+
conditions.push(
62+
"EXISTS (SELECT 1 FROM json_each(posts.tags) WHERE value = ?)".to_string(),
63+
);
5664
params.push(Box::new(tag));
5765
}
5866

@@ -65,6 +73,18 @@ impl SearchService {
6573
params.push(Box::new(date));
6674
}
6775

76+
if !post_types_as_strings.is_empty() {
77+
let placeholders = post_types_as_strings
78+
.iter()
79+
.map(|_| "?")
80+
.collect::<Vec<_>>()
81+
.join(", ");
82+
conditions.push(format!("posts.content_type IN ({})", placeholders));
83+
for pt_str in &post_types_as_strings {
84+
params.push(Box::new(pt_str.clone()));
85+
}
86+
}
87+
6888
let where_clause = if !conditions.is_empty() {
6989
format!("WHERE {}", conditions.join(" AND "))
7090
} else {

src/services/search_query.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
use regex::Regex;
22

3+
use crate::post::ContentType;
4+
35
#[derive(Debug, Default)]
46
pub struct SearchQuery {
57
pub text_query: String,
68
pub tags: Vec<String>,
79
pub from_date: Option<String>,
810
pub to_date: Option<String>,
11+
pub post_type: Vec<ContentType>,
912
}
1013

1114
impl SearchQuery {
1215
pub fn from_raw(raw: &str) -> Self {
1316
let mut result = SearchQuery::default();
1417
let tag_re = Regex::new(r"tag:([^\s]+)").unwrap();
1518
let date_re = Regex::new(r"(from|to):(\d{4}-\d{2}-\d{2})").unwrap();
19+
let type_re = Regex::new(r"type:(post|link|quote)").unwrap();
1620

1721
// Extract tags
1822
for cap in tag_re.captures_iter(raw) {
@@ -32,9 +36,17 @@ impl SearchQuery {
3236
}
3337
}
3438

39+
// Extract type
40+
for cap in type_re.captures_iter(raw) {
41+
if let Some(p_type) = cap.get(1).map(|m| m.as_str().to_string()) {
42+
result.post_type.push(ContentType::from(p_type));
43+
}
44+
}
45+
3546
// Clean text query
3647
result.text_query = tag_re.replace_all(raw, "").to_string();
3748
result.text_query = date_re.replace_all(&result.text_query, "").to_string();
49+
result.text_query = type_re.replace_all(&result.text_query, "").to_string();
3850
result.text_query = result.text_query.trim().to_string();
3951

4052
result

0 commit comments

Comments
 (0)