Commit
Message
Changed Files (16)
-
modified src/config.rs
diff --git a/src/config.rs b/src/config.rs index ec8b7aa..3961be4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -231,7 +231,7 @@ impl Config { .merge(Toml::file(path)) .extract() .unwrap_or_else(|e| { - eprintln!("Warning: failed to parse config file {:?}: {}", path, e); + eprintln!("Warning: failed to parse config file {path:?}: {e}"); Config::default() }) } else { @@ -369,7 +369,7 @@ instance = "https://search.example.com" #[test] fn tagging_enabled_defaults_to_false() { let cfg = Config::default(); - assert_eq!(cfg.tagging_enabled.unwrap_or(false), false); + assert!(!cfg.tagging_enabled.unwrap_or(false)); } #[test] -
modified src/importer/chrome.rs
diff --git a/src/importer/chrome.rs b/src/importer/chrome.rs index da2940a..f32ed35 100644 --- a/src/importer/chrome.rs +++ b/src/importer/chrome.rs @@ -25,11 +25,10 @@ impl Importer for ChromeImporter { let path = entry.path(); if path.is_dir() { let name = path.file_name().and_then(|n| n.to_str()); - if name == Some("Default") || name.map_or(false, |n| n.starts_with("Profile ")) { - if path.join("Bookmarks").exists() { + if (name == Some("Default") || name.is_some_and(|n| n.starts_with("Profile "))) + && path.join("Bookmarks").exists() { profiles.push(path); } - } } } } @@ -41,7 +40,7 @@ impl Importer for ChromeImporter { fn import(&self, profile_path: &Path) -> anyhow::Result<Vec<Bookmark>> { let bookmarks_path = profile_path.join("Bookmarks"); if !bookmarks_path.exists() { - anyhow::bail!("Bookmarks file not found in {:?}", profile_path); + anyhow::bail!("Bookmarks file not found in {profile_path:?}"); } let content = std::fs::read_to_string(&bookmarks_path)?; -
modified src/importer/mod.rs
diff --git a/src/importer/mod.rs b/src/importer/mod.rs index 7ec3548..1df25af 100644 --- a/src/importer/mod.rs +++ b/src/importer/mod.rs @@ -116,11 +116,11 @@ pub fn open_backup(profile_path: &Path) -> anyhow::Result<Connection> { pub fn open_backup_file(profile_path: &Path, filename: &str) -> anyhow::Result<Connection> { let src = profile_path.join(filename); if !src.exists() { - anyhow::bail!("{} not found in {:?}", filename, profile_path); + anyhow::bail!("{filename} not found in {profile_path:?}"); } let tmp = tempfile::Builder::new() - .suffix(&format!(".{}", filename)) + .suffix(&format!(".{filename}")) .tempfile()?; let tmp_path = tmp.path().to_owned(); std::fs::copy(&src, &tmp_path)?; -
modified src/main.rs
diff --git a/src/main.rs b/src/main.rs index e175be0..0ae9bd1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,7 +82,7 @@ impl Fetcher { let cache = self.robots_cache.lock() .map_err(|_| "internal error: lock poisoned".to_string())?; let expired = cache.get(&domain) - .map_or(true, |e| Utc::now() - e.fetched_at > one_month); + .is_none_or(|e| Utc::now() - e.fetched_at > one_month); !cache.contains_key(&domain) || expired }; @@ -254,17 +254,17 @@ fn print_bookmark(b: &Bookmark) { let title = b.title.bold(); let url = b.url.dimmed(); let time = local_time.format("%Y-%m-%d %H:%M:%S").to_string().dimmed(); - println!("{} {} {}", id_str, title, url); + println!("{id_str} {title} {url}"); if let Some(tags) = b.tags.as_ref().filter(|t| !t.is_empty()) { let tag_parts: Vec<_> = tags.split(", ").filter_map(|t| { let trimmed = t.trim(); - if trimmed.is_empty() { None } else { Some(format!("[{}]", trimmed).yellow().to_string()) } + if trimmed.is_empty() { None } else { Some(format!("[{trimmed}]").yellow().to_string()) } }).collect(); if !tag_parts.is_empty() { println!(" {} {}", time, tag_parts.join(" ")); } } else { - println!(" {}", time); + println!(" {time}"); } } @@ -373,14 +373,14 @@ async fn main() { let conn = storage::init_db(&db_path.to_string_lossy()).expect("Failed to open database"); if url::Url::parse(&url).is_err() { - eprintln!("Error: invalid URL '{}'", url); + eprintln!("Error: invalid URL '{url}'"); return; } let mut fetcher = match Fetcher::new(cache_path.clone()) { Ok(f) => f, Err(e) => { - eprintln!("Warning: failed to create HTTP client: {}", e); + eprintln!("Warning: failed to create HTTP client: {e}"); let bookmark = Bookmark { id: 0, title, @@ -421,7 +421,7 @@ async fn main() { } } Err(e) => { - eprintln!("Warning: failed to initialize tagger: {}", e); + eprintln!("Warning: failed to initialize tagger: {e}"); None } } @@ -460,7 +460,7 @@ async fn main() { let bookmarks = storage::search_bookmarks(&conn, &query, 1, 10000).expect("Failed to search"); if bookmarks.is_empty() { - println!("No results for \"{}\"", query); + println!("No results for \"{query}\""); return; } @@ -482,7 +482,7 @@ async fn main() { let mut engine = match TaggingEngine::new(&tags, tag_threshold, max_tags, truncation, &onnx_model) { Ok(e) => e, Err(e) => { - eprintln!("Warning: failed to initialize tagger: {}", e); + eprintln!("Warning: failed to initialize tagger: {e}"); return; } }; @@ -555,30 +555,30 @@ async fn main() { Ok(tags) => { let tags_str = if tags.is_empty() { None } else { Some(tags.join(", ")) }; storage::update_bookmark_tags(&conn, *rowid, tags_str.as_deref()) - .unwrap_or_else(|e| eprintln!("Warning: failed to update tags: {}", e)); + .unwrap_or_else(|e| eprintln!("Warning: failed to update tags: {e}")); tagged += 1; pb.set_message(format!("{} tagged", "✓")); } Err(e) => { - eprintln!("Warning: tagging failed for #{}: {}", rowid, e); + eprintln!("Warning: tagging failed for #{rowid}: {e}"); skipped += 1; pb.set_message(format!("{} failed", "✘")); } } } None => { - eprintln!("Warning: #{} has no content, skipping", rowid); + eprintln!("Warning: #{rowid} has no content, skipping"); skipped += 1; pb.set_message(format!("{} no content", "✘")); } } } Ok(None) => { - eprintln!("Warning: bookmark #{} not found", rowid); + eprintln!("Warning: bookmark #{rowid} not found"); skipped += 1; } Err(e) => { - eprintln!("Warning: failed to read bookmark #{}: {}", rowid, e); + eprintln!("Warning: failed to read bookmark #{rowid}: {e}"); skipped += 1; } } @@ -588,16 +588,16 @@ async fn main() { pb.finish_with_message(format!("{} {} tagged, {} {} skipped", "✔", tagged, "✘", skipped)); } Command::InitConfig => { - let path = config_path.clone().unwrap_or_else(|| config_file_path()); + let path = config_path.clone().unwrap_or_else(config_file_path); if path.exists() { - eprintln!("Config file already exists at {:?}", path); + eprintln!("Config file already exists at {path:?}"); return; } let default_db = storage::default_db_path(); let home = std::env::var("HOME").unwrap_or_default(); let default_display = default_db.to_string_lossy(); let default_display = if let Some(rest) = default_display.strip_prefix(&home) { - format!("~{}", rest) + format!("~{rest}") } else { default_display.to_string() }; @@ -605,7 +605,7 @@ async fn main() { "# SearchHub configuration\n\ \n\ # Bookmark database path (default: platform data directory)\n\ - # db_path = \"{}\"\n\ + # db_path = \"{default_display}\"\n\ \n\ # Custom tags override the built-in defaults\n\ # [[tags]]\n\ @@ -628,15 +628,13 @@ async fn main() { # instance = \"https://search.kael.ink\"\n\ # Best: use an existing public instance (see https://searx.space).\n\ # Also possible: run your own with Docker:\n\ - # docker run -d --name searxng -p 8888:8080 searxng/searxng\n", - - default_display + # docker run -d --name searxng -p 8888:8080 searxng/searxng\n" ); if let Some(parent) = path.parent() { tokio::fs::create_dir_all(parent).await.expect("Failed to create config directory"); } tokio::fs::write(&path, content).await.expect("Failed to write config file"); - println!("Default config created at {:?}", path); + println!("Default config created at {path:?}"); } Command::SelfUpdate { feed_url, target, dry_run } => { let mut updater = search_hub::self_update::SelfUpdate::new() @@ -723,13 +721,14 @@ fn resolve_profiles(importer: &(impl Importer + ?Sized), profile: Option<String> } } +#[allow(clippy::too_many_arguments)] async fn run_import(source: &str, profile: Option<String>, db_path: &str, tags: Vec<TagDef>, tagging_enabled: bool, tag_threshold: f32, exclude_hosts: &[String], kind: ImportKind, cache_path: PathBuf, max_tags: usize, truncation: usize, onnx_model: String) { let importer: Box<dyn Importer> = match source { "firefox" => Box::new(FirefoxImporter), "zen" => Box::new(ZenImporter), "chrome" | "chromium" => Box::new(ChromeImporter), other => { - eprintln!("Unknown browser source: '{}'. Supported: firefox, zen, chrome, chromium", other); + eprintln!("Unknown browser source: '{other}'. Supported: firefox, zen, chrome, chromium"); std::process::exit(1); } }; @@ -756,7 +755,7 @@ async fn run_import(source: &str, profile: Option<String>, db_path: &str, tags: match result { Ok(mut entries) => all_entries.append(&mut entries), Err(e) => { - eprintln!("Warning: failed to import {} from {:?}: {}", label, profile_path, e); + eprintln!("Warning: failed to import {label} from {profile_path:?}: {e}"); } } } @@ -768,7 +767,7 @@ async fn run_import(source: &str, profile: Option<String>, db_path: &str, tags: let total = all_entries.len(); if total == 0 { - println!("No {} found to import.", label); + println!("No {label} found to import."); return; } @@ -830,7 +829,7 @@ async fn run_import(source: &str, profile: Option<String>, db_path: &str, tags: .map(|n| n.get()) .unwrap_or(4) .max(1); - let chunk_size = (pending.len() + num_threads - 1) / num_threads; + let chunk_size = pending.len().div_ceil(num_threads); let tasks: Vec<_> = pending.chunks(chunk_size).enumerate().map(|(task_id, chunk)| { let owned: Vec<_> = chunk.to_vec(); @@ -847,7 +846,7 @@ async fn run_import(source: &str, profile: Option<String>, db_path: &str, tags: let mut fetcher = match Fetcher::new(task_cache) { Ok(f) => f, Err(e) => { - let _ = tx.send(format!("[{}] failed to create HTTP client: {}", task_id, e)); + let _ = tx.send(format!("[{task_id}] failed to create HTTP client: {e}")); return; } }; @@ -864,19 +863,16 @@ async fn run_import(source: &str, profile: Option<String>, db_path: &str, tags: bar.inc(1); continue; } - match fetch_and_convert(&mut fetcher, url, Some(task_id)) { - Some(md) => { - let entry_tags = tagger.as_mut() - .and_then(|e| e.tags_for(&md).ok()) - .unwrap_or_default(); - let tags_str = if entry_tags.is_empty() { None } else { Some(entry_tags.join(", ")) }; - storage::update_bookmark_content_tags( - &conn, *rowid, Some(&md), tags_str.as_deref(), - ).unwrap_or_else(|e| { - let _ = tx.send(format!("failed to update bookmark {}: {}", rowid, e)); - }); - } - None => {} + if let Some(md) = fetch_and_convert(&mut fetcher, url, Some(task_id)) { + let entry_tags = tagger.as_mut() + .and_then(|e| e.tags_for(&md).ok()) + .unwrap_or_default(); + let tags_str = if entry_tags.is_empty() { None } else { Some(entry_tags.join(", ")) }; + storage::update_bookmark_content_tags( + &conn, *rowid, Some(&md), tags_str.as_deref(), + ).unwrap_or_else(|e| { + let _ = tx.send(format!("failed to update bookmark {rowid}: {e}")); + }); } bar.inc(1); } @@ -889,7 +885,7 @@ async fn run_import(source: &str, profile: Option<String>, db_path: &str, tags: while let Ok(err) = rx.recv() { if error_buffer.len() < 10 { error_buffer.push_back(err.clone()); - eprintln!("{}", err); + eprintln!("{err}"); } else { error_buffer.pop_front(); error_buffer.push_back(err); @@ -925,22 +921,22 @@ fn is_excluded_url(url: &str, exclude_hosts: &[String]) -> bool { Some(url::Host::Ipv6(ip)) => Some(ip.to_string()), None => None, }) - .map(|host| exclude_hosts.iter().any(|e| host == *e)) + .map(|host| exclude_hosts.contains(&host)) .unwrap_or(false) } fn fetch_and_convert(fetcher: &mut Fetcher, url: &str, task_id: Option<usize>) -> Option<String> { - let prefix = task_id.map(|id| format!("[importer-{}] ", id)).unwrap_or_default(); + let prefix = task_id.map(|id| format!("[importer-{id}] ")).unwrap_or_default(); match fetcher.fetch(url) { Ok(html) => match htmd::convert(&html) { Ok(md) => Some(md), Err(e) => { - eprintln!("{}Warning: failed to convert HTML to Markdown: {}", prefix, e); + eprintln!("{prefix}Warning: failed to convert HTML to Markdown: {e}"); None } }, Err(e) => { - eprintln!("{}Warning: failed to fetch URL '{}': {}", prefix, url, e); + eprintln!("{prefix}Warning: failed to fetch URL '{url}': {e}"); None } } @@ -987,10 +983,8 @@ mod tests { fn fetcher_fetch_basic_page() { let (listener, port) = test_server(); std::thread::spawn(move || { - for stream in listener.incoming() { - if let Ok(stream) = stream { - handle_connection(stream); - } + for stream in listener.incoming().flatten() { + handle_connection(stream); } }); @@ -999,7 +993,7 @@ mod tests { let mut fetcher = Fetcher::new(cache_path).unwrap(); let result = fetcher.fetch(&format!("http://127.0.0.1:{port}/page")); - assert!(result.is_ok(), "fetch should succeed: {:?}", result); + assert!(result.is_ok(), "fetch should succeed: {result:?}"); assert!(result.unwrap().contains("hello")); } @@ -1007,10 +1001,8 @@ mod tests { fn fetcher_blocks_disallowed_path() { let (listener, port) = test_server(); std::thread::spawn(move || { - for stream in listener.incoming() { - if let Ok(stream) = stream { - handle_connection(stream); - } + for stream in listener.incoming().flatten() { + handle_connection(stream); } }); @@ -1020,7 +1012,7 @@ mod tests { // First request fetches robots.txt let result = fetcher.fetch(&format!("http://127.0.0.1:{port}/page")); - assert!(result.is_ok(), "first fetch should succeed: {:?}", result); + assert!(result.is_ok(), "first fetch should succeed: {result:?}"); // Second request to disallowed path should be blocked let result = fetcher.fetch(&format!("http://127.0.0.1:{port}/private/page")); @@ -1034,24 +1026,23 @@ mod tests { let request_count = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0)); let count = request_count.clone(); std::thread::spawn(move || { - for stream in listener.incoming() { - if let Ok(mut stream) = stream { - count.fetch_add(1, std::sync::atomic::Ordering::SeqCst); - let mut buf = [0; 4096]; - let _ = stream.read(&mut buf); - let request = String::from_utf8_lossy(&buf[..]); - let (status, body) = if request.contains("/robots.txt") { - ("200 OK", "User-agent: *\nDisallow:\n") - } else { - ("200 OK", "<html><body>hello</body></html>") - }; - let response = format!( - "HTTP/1.1 {status}\r\nContent-Type: text/plain\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{body}", - body.len() - ); - let _ = stream.write_all(response.as_bytes()); - let _ = stream.flush(); - } + for stream in listener.incoming().flatten() { + let mut stream = stream; + count.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + let mut buf = [0; 4096]; + let _ = stream.read(&mut buf); + let request = String::from_utf8_lossy(&buf[..]); + let (status, body) = if request.contains("/robots.txt") { + ("200 OK", "User-agent: *\nDisallow:\n") + } else { + ("200 OK", "<html><body>hello</body></html>") + }; + let response = format!( + "HTTP/1.1 {status}\r\nContent-Type: text/plain\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{body}", + body.len() + ); + let _ = stream.write_all(response.as_bytes()); + let _ = stream.flush(); } }); -
modified src/search_engines/crates_io.rs
diff --git a/src/search_engines/crates_io.rs b/src/search_engines/crates_io.rs index b9b0b68..72250b7 100644 --- a/src/search_engines/crates_io.rs +++ b/src/search_engines/crates_io.rs @@ -44,7 +44,7 @@ impl SearchEngine for CratesIo { fn timeout(&self) -> std::time::Duration { self.timeout_secs - .map(|s| std::time::Duration::from_secs_f32(s)) + .map(std::time::Duration::from_secs_f32) .unwrap_or_else(|| std::time::Duration::from_secs(5)) } -
modified src/search_engines/generic.rs
diff --git a/src/search_engines/generic.rs b/src/search_engines/generic.rs index d064ccd..26dfde2 100644 --- a/src/search_engines/generic.rs +++ b/src/search_engines/generic.rs @@ -37,7 +37,7 @@ impl SearchEngine for Generic { fn timeout(&self) -> Duration { self.timeout_secs - .map(|s| Duration::from_secs_f32(s)) + .map(Duration::from_secs_f32) .unwrap_or(Duration::from_secs(5)) } } -
modified src/search_engines/mdn.rs
diff --git a/src/search_engines/mdn.rs b/src/search_engines/mdn.rs index 91c27ba..e46ce3a 100644 --- a/src/search_engines/mdn.rs +++ b/src/search_engines/mdn.rs @@ -43,7 +43,7 @@ impl SearchEngine for Mdn { fn timeout(&self) -> std::time::Duration { self.timeout_secs - .map(|s| std::time::Duration::from_secs_f32(s)) + .map(std::time::Duration::from_secs_f32) .unwrap_or_else(|| std::time::Duration::from_secs(5)) } -
modified src/search_engines/searxng.rs
diff --git a/src/search_engines/searxng.rs b/src/search_engines/searxng.rs index 5d8218e..576da7a 100644 --- a/src/search_engines/searxng.rs +++ b/src/search_engines/searxng.rs @@ -42,7 +42,7 @@ impl SearchEngine for SearXng { fn timeout(&self) -> std::time::Duration { self.timeout_secs - .map(|s| std::time::Duration::from_secs_f32(s)) + .map(std::time::Duration::from_secs_f32) .unwrap_or_else(|| std::time::Duration::from_secs(5)) } -
modified src/search_engines/utils.rs
diff --git a/src/search_engines/utils.rs b/src/search_engines/utils.rs index e4d165d..d508462 100644 --- a/src/search_engines/utils.rs +++ b/src/search_engines/utils.rs @@ -5,9 +5,9 @@ pub fn urlencode(s: &str) -> String { b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => { out.push(byte as char); } - b' ' => out.push_str("+"), + b' ' => out.push('+'), _ => { - out.push_str(&format!("%{:02X}", byte)); + out.push_str(&format!("%{byte:02X}")); } } } @@ -34,8 +34,8 @@ pub fn decode_html_entities(s: &str) -> String { "quot" => "\"", "apos" => "'", _ => { - if entity.starts_with('#') { - if let Ok(code) = entity[1..].parse::<u32>() { + if let Some(stripped) = entity.strip_prefix('#') { + if let Ok(code) = stripped.parse::<u32>() { if let Some(c) = char::from_u32(code) { out.push(c); continue; -
modified src/search_engines/wikipedia.rs
diff --git a/src/search_engines/wikipedia.rs b/src/search_engines/wikipedia.rs index f69c251..32a4119 100644 --- a/src/search_engines/wikipedia.rs +++ b/src/search_engines/wikipedia.rs @@ -52,7 +52,7 @@ impl SearchEngine for Wikipedia { fn timeout(&self) -> std::time::Duration { self.timeout_secs - .map(|s| std::time::Duration::from_secs_f32(s)) + .map(std::time::Duration::from_secs_f32) .unwrap_or_else(|| std::time::Duration::from_secs(5)) } -
modified src/self_update.rs
diff --git a/src/self_update.rs b/src/self_update.rs index e8b246c..4f960e9 100644 --- a/src/self_update.rs +++ b/src/self_update.rs @@ -15,12 +15,12 @@ impl FromStr for Version { let s = s.strip_prefix('v').unwrap_or(s); let parts: Vec<&str> = s.splitn(3, '.').collect(); if parts.len() != 3 { - return Err(format!("invalid version: {}", s)); + return Err(format!("invalid version: {s}")); } Ok(Version( - parts[0].parse().map_err(|_| format!("invalid major in {}", s))?, - parts[1].parse().map_err(|_| format!("invalid minor in {}", s))?, - parts[2].parse().map_err(|_| format!("invalid patch in {}", s))?, + parts[0].parse().map_err(|_| format!("invalid major in {s}"))?, + parts[1].parse().map_err(|_| format!("invalid minor in {s}"))?, + parts[2].parse().map_err(|_| format!("invalid patch in {s}"))?, )) } } @@ -114,7 +114,7 @@ impl SelfUpdate { pub async fn run(&self) -> Result<()> { let client = Client::builder() - .user_agent(&user_agent()) + .user_agent(user_agent()) .build()?; println!("Checking for updates at {}...", self.feed_url); @@ -145,7 +145,7 @@ impl SelfUpdate { let latest_version = match latest { Some((v, s)) => { - println!("Latest release: {}", s); + println!("Latest release: {s}"); v } None => { @@ -156,20 +156,19 @@ impl SelfUpdate { if latest_version <= current { println!( - "Already up to date (current: {}, latest: {})", - current, latest_version + "Already up to date (current: {current}, latest: {latest_version})" ); return Ok(()); } - println!("Update available: {} -> {}", current, latest_version); + println!("Update available: {current} -> {latest_version}"); if self.dry_run { let url = format!( "https://vit.am/~ololduck/search_hub/{}/dist/search_hub-{}-{}", latest_version, latest_version, self.target ); - println!("Would download: {}", url); + println!("Would download: {url}"); return Ok(()); } @@ -178,7 +177,7 @@ impl SelfUpdate { latest_version, latest_version, self.target ); - println!("Downloading {}...", url); + println!("Downloading {url}..."); let response = client .get(&url) .send() @@ -225,7 +224,7 @@ impl SelfUpdate { .context("Failed to replace current binary - maybe missing write permission? \ Try running with sudo or reinstall via cargo install --path .")?; - println!("Successfully updated to v{}!", latest_version); + println!("Successfully updated to v{latest_version}!"); println!("Restart any running search_hub processes to use the new version."); Ok(()) @@ -311,7 +310,7 @@ mod tests { #[test] fn selects_highest_version() { - let versions = vec!["0.2.0".to_string(), "0.3.0".to_string(), "0.1.0".to_string()]; + let versions = ["0.2.0".to_string(), "0.3.0".to_string(), "0.1.0".to_string()]; let latest = versions .iter() .filter_map(|s| { -
modified src/storage.rs
diff --git a/src/storage.rs b/src/storage.rs index 52daf51..2268831 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -68,8 +68,8 @@ pub fn init_db(path: &str) -> Result<Connection> { }) .unwrap_or_default(); - if !cols.iter().any(|c| c == "content") { - if conn.execute("ALTER TABLE bookmarks ADD COLUMN content TEXT", []).is_err() { + if !cols.iter().any(|c| c == "content") + && conn.execute("ALTER TABLE bookmarks ADD COLUMN content TEXT", []).is_err() { conn.execute_batch( "CREATE TABLE bookmarks_backup AS SELECT rowid, id, title, url, description, created_at FROM bookmarks; DROP TABLE IF EXISTS bookmarks; @@ -81,10 +81,9 @@ pub fn init_db(path: &str) -> Result<Connection> { DROP TABLE bookmarks_backup;", )?; } - } - if !cols.iter().any(|c| c == "tags") { - if conn.execute("ALTER TABLE bookmarks ADD COLUMN tags TEXT", []).is_err() { + if !cols.iter().any(|c| c == "tags") + && conn.execute("ALTER TABLE bookmarks ADD COLUMN tags TEXT", []).is_err() { let _existing_cols = cols.join(", "); conn.execute_batch( &format!("CREATE TABLE bookmarks_backup AS SELECT rowid, id, title, url, description, {}, created_at FROM bookmarks; @@ -101,10 +100,9 @@ pub fn init_db(path: &str) -> Result<Connection> { ), )?; } - } - if !cols.iter().any(|c| c == "source") { - if conn.execute("ALTER TABLE bookmarks ADD COLUMN source TEXT", []).is_err() { + if !cols.iter().any(|c| c == "source") + && conn.execute("ALTER TABLE bookmarks ADD COLUMN source TEXT", []).is_err() { conn.execute_batch( "CREATE TABLE bookmarks_backup AS SELECT rowid, id, title, url, description, content, tags, created_at FROM bookmarks; DROP TABLE IF EXISTS bookmarks; @@ -116,7 +114,6 @@ pub fn init_db(path: &str) -> Result<Connection> { DROP TABLE bookmarks_backup;", )?; } - } Ok(conn) } -
modified src/tagging.rs
diff --git a/src/tagging.rs b/src/tagging.rs index 2c7dce3..27ee9cb 100644 --- a/src/tagging.rs +++ b/src/tagging.rs @@ -16,7 +16,7 @@ fn parse_model(name: &str) -> anyhow::Result<EmbeddingModel> { Ok(match name { "AllMiniLML6V2" => EmbeddingModel::AllMiniLML6V2, "BGESmallENV15" => EmbeddingModel::BGESmallENV15, - other => anyhow::bail!("unknown ONNX model '{}'", other), + other => anyhow::bail!("unknown ONNX model '{other}'"), }) } @@ -241,7 +241,7 @@ impl TaggingEngine { for (ti, tag) in tags.iter().enumerate() { for example in &tag.examples { tag_indices.push((ti, &tag.name)); - all_examples.push(format!("passage: {}", example)); + all_examples.push(format!("passage: {example}")); } } -
modified src/web.rs
diff --git a/src/web.rs b/src/web.rs index 29d8676..25fe497 100644 --- a/src/web.rs +++ b/src/web.rs @@ -87,7 +87,7 @@ async fn search( } else { storage::count_bookmarks(&db_pool.conn()).unwrap_or(0) }; - let total_pages = (total_results + page_size - 1) / page_size; + let total_pages = total_results.div_ceil(page_size); let bookmarks = if has_query { storage::search_bookmarks(&db_pool.conn(), q, page, page_size).unwrap_or_default() @@ -131,8 +131,7 @@ async fn search( Err(_) => ( engine_name, Err(EngineError(format!( - "timed out after {:?}", - timeout_dur + "timed out after {timeout_dur:?}" ))), elapsed, ), -
modified tests/convert_strips_html.rs
diff --git a/tests/convert_strips_html.rs b/tests/convert_strips_html.rs index 0ca47f3..785b7bf 100644 --- a/tests/convert_strips_html.rs +++ b/tests/convert_strips_html.rs @@ -19,13 +19,13 @@ fn fetch(url: &str) -> String { fn print_md(name: &str, html: &str, md: &str) { println!(); - println!("=== {} ===", name); + println!("=== {name} ==="); println!("Raw HTML : {} bytes", html.len()); println!("Markdown : {} bytes", md.len()); println!("Ratio : {:.1}x smaller", html.len() as f64 / md.len().max(1) as f64); println!(); println!("--- Markdown output ---"); - println!("{}", md); + println!("{md}"); println!("--- end ---"); } -
modified tests/tagging_thresholds.rs
diff --git a/tests/tagging_thresholds.rs b/tests/tagging_thresholds.rs index 9730dac..c0889db 100644 --- a/tests/tagging_thresholds.rs +++ b/tests/tagging_thresholds.rs @@ -414,11 +414,11 @@ fn explore_tagging_thresholds() { .expect("tagging failed"); if matched.is_empty() { - println!(" {:.2}: (none)", threshold); + println!(" {threshold:.2}: (none)"); } else { let tags_repr: Vec<String> = matched .iter() - .map(|(tag, score)| format!("{} ({:.3})", tag, score)) + .map(|(tag, score)| format!("{tag} ({score:.3})")) .collect(); println!(" {:.2}: {}", threshold, tags_repr.join(", ")); }