1use url::Url;
8
9pub use crate::Query;
11
12#[derive(Default, Debug)]
14#[cfg_attr(feature = "cli", derive(clap::Args))]
15pub struct EngineOptions {
16 #[cfg_attr(feature = "cli", arg(long))]
20 pub keep_ads: bool,
21
22 #[cfg_attr(feature = "cli", arg(long))]
26 pub keep_videos: bool,
27
28 #[cfg_attr(feature = "cli", arg(long))]
32 pub keep_images: bool,
33}
34
35#[derive(Debug)]
37pub struct SearchResult {
38 pub title: String,
40
41 pub description: String,
43
44 pub source: Url,
46}
47
48pub type SearchResults = Vec<SearchResult>;
50
51impl SearchResult {
52 pub fn try_new<T: Into<String>>(
54 title: T,
55 description: T,
56 source: &str,
57 ) -> Result<Self, Box<dyn std::error::Error>> {
58 Ok(Self {
59 title: title.into(),
60 description: description.into(),
61 source: Url::parse(source)?,
62 })
63 }
64}
65
66impl std::fmt::Display for SearchResult {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 let desc_slice = &self.description[..std::cmp::min(self.description.len(), 40)];
73
74 write!(f, "{} ({}): \"{}...\"", self.title, self.source, desc_slice)
75 }
76}
77
78pub trait Soap {
80 fn configure(&mut self, options: EngineOptions) -> Result<(), Box<dyn std::error::Error>>;
82
83 fn search(&self, query: Query) -> Result<SearchResults, Box<dyn std::error::Error>>;
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn test_search_result_create() {
93 let result = SearchResult::try_new("title", "description", "https://example.com");
94 assert!(result.is_ok());
95 }
96
97 #[test]
98 fn test_search_result_display() {
99 let result = SearchResult::try_new("title", "description", "https://example.com").unwrap();
100 assert_eq!(
101 result.to_string(),
102 "title (https://example.com/): \"description...\""
103 );
104 }
105
106 #[test]
107 fn test_search_result_display_desc_is_truncated() {
108 let desc = "description description description description";
109 let result = SearchResult::try_new("title", desc, "https://example.com").unwrap();
110 assert_eq!(
111 result.to_string(),
112 format!("title (https://example.com/): \"{}...\"", &desc[..40])
113 );
114 }
115}