chore: cargo fmt

This commit is contained in:
Till Wegmueller 2026-01-18 12:51:55 +01:00
parent 8f089656ba
commit 9512eb3b12
No known key found for this signature in database
6 changed files with 288 additions and 123 deletions

View file

@ -18,7 +18,11 @@ use super::{RepositoryError, Result};
struct PythonFormatter; struct PythonFormatter;
impl Formatter for PythonFormatter { impl Formatter for PythonFormatter {
fn begin_object_key<W: ?Sized + Write>(&mut self, writer: &mut W, first: bool) -> std::io::Result<()> { fn begin_object_key<W: ?Sized + Write>(
&mut self,
writer: &mut W,
first: bool,
) -> std::io::Result<()> {
if !first { if !first {
writer.write_all(b",")?; writer.write_all(b",")?;
} }
@ -29,7 +33,11 @@ impl Formatter for PythonFormatter {
writer.write_all(b":") writer.write_all(b":")
} }
fn begin_array_value<W: ?Sized + Write>(&mut self, writer: &mut W, first: bool) -> std::io::Result<()> { fn begin_array_value<W: ?Sized + Write>(
&mut self,
writer: &mut W,
first: bool,
) -> std::io::Result<()> {
if !first { if !first {
writer.write_all(b",")?; writer.write_all(b",")?;
} }

View file

@ -10,7 +10,7 @@ use lz4::EncoderBuilder;
use regex::Regex; use regex::Regex;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::{Digest as Sha2Digest, Sha256}; use sha2::{Digest as Sha2Digest, Sha256};
use std::collections::{HashMap, HashSet, BTreeMap}; use std::collections::{BTreeMap, HashMap, HashSet};
use std::fs; use std::fs;
use std::fs::File; use std::fs::File;
use std::io::{Read, Write}; use std::io::{Read, Write};
@ -23,7 +23,7 @@ use walkdir::WalkDir;
use crate::actions::{File as FileAction, Manifest}; use crate::actions::{File as FileAction, Manifest};
use crate::digest::Digest; use crate::digest::Digest;
use crate::fmri::Fmri; use crate::fmri::Fmri;
use crate::payload::{Payload, PayloadCompressionAlgorithm, PayloadArchitecture, PayloadBits}; use crate::payload::{Payload, PayloadArchitecture, PayloadBits, PayloadCompressionAlgorithm};
use super::catalog_writer; use super::catalog_writer;
use super::{ use super::{
@ -74,17 +74,48 @@ struct SearchQuery {
fn parse_query(query: &str) -> SearchQuery { fn parse_query(query: &str) -> SearchQuery {
if !query.contains(':') { if !query.contains(':') {
return SearchQuery { pkg: None, action: None, index: None, token: query.to_string() }; return SearchQuery {
pkg: None,
action: None,
index: None,
token: query.to_string(),
};
} }
let parts: Vec<&str> = query.split(':').collect(); let parts: Vec<&str> = query.split(':').collect();
let get_opt = |s: &str| if s.is_empty() { None } else { Some(s.to_string()) }; let get_opt = |s: &str| {
if s.is_empty() {
None
} else {
Some(s.to_string())
}
};
match parts.len() { match parts.len() {
2 => SearchQuery { pkg: None, action: None, index: get_opt(parts[0]), token: parts[1].to_string() }, 2 => SearchQuery {
3 => SearchQuery { pkg: None, action: get_opt(parts[0]), index: get_opt(parts[1]), token: parts[2].to_string() }, pkg: None,
4 => SearchQuery { pkg: get_opt(parts[0]), action: get_opt(parts[1]), index: get_opt(parts[2]), token: parts[3].to_string() }, action: None,
_ => SearchQuery { pkg: None, action: None, index: None, token: query.to_string() }, index: get_opt(parts[0]),
token: parts[1].to_string(),
},
3 => SearchQuery {
pkg: None,
action: get_opt(parts[0]),
index: get_opt(parts[1]),
token: parts[2].to_string(),
},
4 => SearchQuery {
pkg: get_opt(parts[0]),
action: get_opt(parts[1]),
index: get_opt(parts[2]),
token: parts[3].to_string(),
},
_ => SearchQuery {
pkg: None,
action: None,
index: None,
token: query.to_string(),
},
} }
} }
@ -130,7 +161,15 @@ impl SearchIndex {
} }
/// Add a term to the index for a package /// Add a term to the index for a package
fn add_term(&mut self, term: &str, fmri: &str, action_type: &str, index_type: &str, value: &str, attributes: Option<BTreeMap<String, String>>) { fn add_term(
&mut self,
term: &str,
fmri: &str,
action_type: &str,
index_type: &str,
value: &str,
attributes: Option<BTreeMap<String, String>>,
) {
let token = term.to_string(); let token = term.to_string();
// Convert term to lowercase for case-insensitive search // Convert term to lowercase for case-insensitive search
let term_lower = term.to_lowercase(); let term_lower = term.to_lowercase();
@ -165,7 +204,7 @@ impl SearchIndex {
// Actually man page says `pkg_name` is implicit. // Actually man page says `pkg_name` is implicit.
// Let's index it as: action="pkg", index="name", value=stem // Let's index it as: action="pkg", index="name", value=stem
self.add_term(stem, &fmri, "pkg", "name", stem, None); self.add_term(stem, &fmri, "pkg", "name", stem, None);
// Also index parts of the stem if it contains '/'? // Also index parts of the stem if it contains '/'?
// Legacy behavior might index tokens. // Legacy behavior might index tokens.
for part in stem.split('/') { for part in stem.split('/') {
@ -250,7 +289,7 @@ impl SearchIndex {
let parsed = parse_query(term_str); let parsed = parse_query(term_str);
let token_has_wildcard = parsed.token.contains('*') || parsed.token.contains('?'); let token_has_wildcard = parsed.token.contains('*') || parsed.token.contains('?');
let token_lower = parsed.token.to_lowercase(); let token_lower = parsed.token.to_lowercase();
let mut term_entries: Vec<&IndexEntry> = Vec::new(); let mut term_entries: Vec<&IndexEntry> = Vec::new();
if token_has_wildcard { if token_has_wildcard {
@ -267,47 +306,62 @@ impl SearchIndex {
term_entries.extend(entries); term_entries.extend(entries);
} }
} }
// Filter entries based on structured query and case sensitivity // Filter entries based on structured query and case sensitivity
let filtered: Vec<&IndexEntry> = term_entries.into_iter().filter(|e| { let filtered: Vec<&IndexEntry> = term_entries
// Check Index Type .into_iter()
if let Some(idx) = &parsed.index { .filter(|e| {
if &e.index_type != idx { return false; } // Check Index Type
} if let Some(idx) = &parsed.index {
// Check Action Type if &e.index_type != idx {
if let Some(act) = &parsed.action { return false;
if &e.action_type != act { return false; } }
} }
// Check Package Name (FMRI) // Check Action Type
if let Some(pkg) = &parsed.pkg { if let Some(act) = &parsed.action {
let pkg_has_wildcard = pkg.contains('*') || pkg.contains('?'); if &e.action_type != act {
if pkg_has_wildcard { return false;
let re_str = glob_to_regex(&pkg.to_lowercase()); }
if let Ok(re) = Regex::new(&re_str) { }
// FMRIs are usually lowercase, but let's compare lowercase to be safe/consistent // Check Package Name (FMRI)
if !re.is_match(&e.fmri.to_lowercase()) { return false; } if let Some(pkg) = &parsed.pkg {
let pkg_has_wildcard = pkg.contains('*') || pkg.contains('?');
if pkg_has_wildcard {
let re_str = glob_to_regex(&pkg.to_lowercase());
if let Ok(re) = Regex::new(&re_str) {
// FMRIs are usually lowercase, but let's compare lowercase to be safe/consistent
if !re.is_match(&e.fmri.to_lowercase()) {
return false;
}
}
} else {
if !e.fmri.contains(pkg) {
return false;
}
} }
} else {
if !e.fmri.contains(pkg) { return false; }
} }
}
// Check Case Sensitivity on VALUE // Check Case Sensitivity on VALUE
if case_sensitive { if case_sensitive {
if token_has_wildcard { if token_has_wildcard {
let re_str = glob_to_regex(&parsed.token); // Original token let re_str = glob_to_regex(&parsed.token); // Original token
if let Ok(re) = Regex::new(&re_str) { if let Ok(re) = Regex::new(&re_str) {
if !re.is_match(&e.token) { return false; } if !re.is_match(&e.token) {
} return false;
} else { }
if e.token != parsed.token { return false; } }
} } else {
} if e.token != parsed.token {
return false;
true }
}).collect(); }
}
if filtered.is_empty() { true
})
.collect();
if filtered.is_empty() {
return Vec::new(); // Term found no matches return Vec::new(); // Term found no matches
} }
@ -334,7 +388,8 @@ impl SearchIndex {
} }
results.sort_by(|a, b| { results.sort_by(|a, b| {
a.fmri.cmp(&b.fmri) a.fmri
.cmp(&b.fmri)
.then(a.action_type.cmp(&b.action_type)) .then(a.action_type.cmp(&b.action_type))
.then(a.index_type.cmp(&b.index_type)) .then(a.index_type.cmp(&b.index_type))
.then(a.value.cmp(&b.value)) .then(a.value.cmp(&b.value))
@ -388,7 +443,6 @@ pub struct FileBackend {
Option<std::cell::RefCell<crate::repository::obsoleted::ObsoletedPackageManager>>, Option<std::cell::RefCell<crate::repository::obsoleted::ObsoletedPackageManager>>,
} }
/// Transaction for publishing packages /// Transaction for publishing packages
pub struct Transaction { pub struct Transaction {
/// Unique ID for the transaction /// Unique ID for the transaction
@ -1666,7 +1720,7 @@ impl ReadableRepository for FileBackend {
if added_fmris.contains(&entry.fmri) { if added_fmris.contains(&entry.fmri) {
continue; continue;
} }
if let Ok(fmri) = Fmri::parse(&entry.fmri) { if let Ok(fmri) = Fmri::parse(&entry.fmri) {
debug!("Adding package to results: {}", fmri); debug!("Adding package to results: {}", fmri);
results.push(PackageInfo { fmri }); results.push(PackageInfo { fmri });
@ -2444,7 +2498,11 @@ impl FileBackend {
info!("Rebuilding catalog (batched) for publisher: {}", publisher); info!("Rebuilding catalog (batched) for publisher: {}", publisher);
let quote_action_value = |s: &str| -> String { let quote_action_value = |s: &str| -> String {
if s.is_empty() || s.contains(char::is_whitespace) || s.contains('"') || s.contains('\'') { if s.is_empty()
|| s.contains(char::is_whitespace)
|| s.contains('"')
|| s.contains('\'')
{
format!("\"{}\"", s.replace("\"", "\\\"")) format!("\"{}\"", s.replace("\"", "\\\""))
} else { } else {
s.to_string() s.to_string()
@ -2541,7 +2599,12 @@ impl FileBackend {
// Extract variant and facet actions // Extract variant and facet actions
for attr in &manifest.attributes { for attr in &manifest.attributes {
if attr.key.starts_with("variant.") || attr.key.starts_with("facet.") { if attr.key.starts_with("variant.") || attr.key.starts_with("facet.") {
let values_str = attr.values.iter().map(|s| quote_action_value(s)).collect::<Vec<_>>().join(" value="); let values_str = attr
.values
.iter()
.map(|s| quote_action_value(s))
.collect::<Vec<_>>()
.join(" value=");
dependency_actions.push(format!("set name={} value={}", attr.key, values_str)); dependency_actions.push(format!("set name={} value={}", attr.key, values_str));
} }
} }
@ -2562,7 +2625,12 @@ impl FileBackend {
&& !attr.key.starts_with("facet.") && !attr.key.starts_with("facet.")
&& attr.key != "pkg.fmri" && attr.key != "pkg.fmri"
{ {
let values_str = attr.values.iter().map(|s| quote_action_value(s)).collect::<Vec<_>>().join(" value="); let values_str = attr
.values
.iter()
.map(|s| quote_action_value(s))
.collect::<Vec<_>>()
.join(" value=");
summary_actions.push(format!("set name={} value={}", attr.key, values_str)); summary_actions.push(format!("set name={} value={}", attr.key, values_str));
} }
} }
@ -2734,7 +2802,8 @@ impl FileBackend {
); );
} }
let update_log_sig = catalog_writer::write_update_log(&update_log_path, &mut update_log)?; let update_log_sig =
catalog_writer::write_update_log(&update_log_path, &mut update_log)?;
debug!("Wrote update log file"); debug!("Wrote update log file");
// Add an update log to catalog.attrs // Add an update log to catalog.attrs
@ -2932,15 +3001,19 @@ impl FileBackend {
match Manifest::parse_file(&path) { match Manifest::parse_file(&path) {
Ok(manifest) => { Ok(manifest) => {
// Look for the pkg.fmri attribute // Look for the pkg.fmri attribute
let fmri_opt = manifest.attributes.iter().find(|a| a.key == "pkg.fmri").and_then(|a| a.values.first()); let fmri_opt = manifest
.attributes
.iter()
.find(|a| a.key == "pkg.fmri")
.and_then(|a| a.values.first());
if let Some(fmri_str) = fmri_opt { if let Some(fmri_str) = fmri_opt {
// Parse the FMRI using our Fmri type // Parse the FMRI using our Fmri type
match Fmri::parse(fmri_str) { match Fmri::parse(fmri_str) {
Ok(parsed_fmri) => { Ok(parsed_fmri) => {
let fmri = parsed_fmri.to_string(); let fmri = parsed_fmri.to_string();
let stem = parsed_fmri.stem().to_string(); let stem = parsed_fmri.stem().to_string();
// Add package mapping // Add package mapping
index.packages.insert(fmri.clone(), stem.clone()); index.packages.insert(fmri.clone(), stem.clone());
@ -2948,19 +3021,30 @@ impl FileBackend {
index.add_term(&stem, &fmri, "pkg", "name", &stem, None); index.add_term(&stem, &fmri, "pkg", "name", &stem, None);
for part in stem.split('/') { for part in stem.split('/') {
if part != stem { if part != stem {
index.add_term(part, &fmri, "pkg", "name", &stem, None); index.add_term(
part, &fmri, "pkg", "name", &stem, None,
);
} }
} }
// 2. Index Publisher // 2. Index Publisher
if let Some(publ) = &parsed_fmri.publisher { if let Some(publ) = &parsed_fmri.publisher {
index.add_term(publ, &fmri, "pkg", "publisher", publ, None); index.add_term(
publ,
&fmri,
"pkg",
"publisher",
publ,
None,
);
} }
// 3. Index Version // 3. Index Version
let version = parsed_fmri.version(); let version = parsed_fmri.version();
if !version.is_empty() { if !version.is_empty() {
index.add_term(&version, &fmri, "pkg", "version", &version, None); index.add_term(
&version, &fmri, "pkg", "version", &version, None,
);
} }
// 4. Index Files with attributes // 4. Index Files with attributes
@ -2970,42 +3054,68 @@ impl FileBackend {
attrs.insert("owner".to_string(), file.owner.clone()); attrs.insert("owner".to_string(), file.owner.clone());
attrs.insert("group".to_string(), file.group.clone()); attrs.insert("group".to_string(), file.group.clone());
attrs.insert("mode".to_string(), file.mode.clone()); attrs.insert("mode".to_string(), file.mode.clone());
if let Some(payload) = &file.payload { if let Some(payload) = &file.payload {
let arch_str = match payload.architecture { let arch_str = match payload.architecture {
PayloadArchitecture::I386 => Some("i386"), PayloadArchitecture::I386 => Some("i386"),
PayloadArchitecture::SPARC => Some("sparc"), PayloadArchitecture::SPARC => Some("sparc"),
_ => None _ => None,
}; };
if let Some(a) = arch_str { if let Some(a) = arch_str {
attrs.insert("elfarch".to_string(), a.to_string()); attrs.insert(
} "elfarch".to_string(),
a.to_string(),
let bits_str = match payload.bitness { );
PayloadBits::Bits64 => Some("64"), }
PayloadBits::Bits32 => Some("32"),
_ => None let bits_str = match payload.bitness {
}; PayloadBits::Bits64 => Some("64"),
if let Some(b) = bits_str { PayloadBits::Bits32 => Some("32"),
attrs.insert("elfbits".to_string(), b.to_string()); _ => None,
} };
if let Some(b) = bits_str {
attrs.insert("pkg.content-hash".to_string(), payload.primary_identifier.to_string()); attrs.insert(
"elfbits".to_string(),
b.to_string(),
);
}
attrs.insert(
"pkg.content-hash".to_string(),
payload.primary_identifier.to_string(),
);
} }
for prop in file.properties { for prop in file.properties {
attrs.insert(prop.key, prop.value); attrs.insert(prop.key, prop.value);
} }
// index=path // index=path
index.add_term(&file.path, &fmri, "file", "path", &file.path, Some(attrs.clone())); index.add_term(
&file.path,
&fmri,
"file",
"path",
&file.path,
Some(attrs.clone()),
);
// index=basename // index=basename
if let Some(basename) = Path::new(&file.path).file_name().and_then(|s| s.to_str()) { if let Some(basename) = Path::new(&file.path)
index.add_term(basename, &fmri, "file", "basename", &file.path, Some(attrs)); .file_name()
.and_then(|s| s.to_str())
{
index.add_term(
basename,
&fmri,
"file",
"basename",
&file.path,
Some(attrs),
);
} }
} }
// 5. Index Directories // 5. Index Directories
for dir in manifest.directories { for dir in manifest.directories {
let mut attrs = BTreeMap::new(); let mut attrs = BTreeMap::new();
@ -3013,32 +3123,66 @@ impl FileBackend {
attrs.insert("owner".to_string(), dir.owner.clone()); attrs.insert("owner".to_string(), dir.owner.clone());
attrs.insert("group".to_string(), dir.group.clone()); attrs.insert("group".to_string(), dir.group.clone());
attrs.insert("mode".to_string(), dir.mode.clone()); attrs.insert("mode".to_string(), dir.mode.clone());
// index=path // index=path
index.add_term(&dir.path, &fmri, "dir", "path", &dir.path, Some(attrs.clone())); index.add_term(
&dir.path,
&fmri,
"dir",
"path",
&dir.path,
Some(attrs.clone()),
);
// index=basename // index=basename
if let Some(basename) = Path::new(&dir.path).file_name().and_then(|s| s.to_str()) { if let Some(basename) = Path::new(&dir.path)
index.add_term(basename, &fmri, "dir", "basename", &dir.path, Some(attrs)); .file_name()
.and_then(|s| s.to_str())
{
index.add_term(
basename,
&fmri,
"dir",
"basename",
&dir.path,
Some(attrs),
);
} }
} }
// 6. Index Dependencies // 6. Index Dependencies
for dep in manifest.dependencies { for dep in manifest.dependencies {
if let Some(dep_fmri) = &dep.fmri { if let Some(dep_fmri) = &dep.fmri {
let dep_fmri_str = dep_fmri.to_string(); let dep_fmri_str = dep_fmri.to_string();
let mut attrs = BTreeMap::new(); let mut attrs = BTreeMap::new();
if !dep.dependency_type.is_empty() { if !dep.dependency_type.is_empty() {
attrs.insert("type".to_string(), dep.dependency_type.clone()); attrs.insert(
"type".to_string(),
dep.dependency_type.clone(),
);
} }
for prop in dep.optional { for prop in dep.optional {
attrs.insert(prop.key, prop.value); attrs.insert(prop.key, prop.value);
} }
index.add_term(&dep_fmri_str, &fmri, "depend", "fmri", &dep_fmri_str, Some(attrs.clone())); index.add_term(
index.add_term(dep_fmri.stem(), &fmri, "depend", "fmri", &dep_fmri_str, Some(attrs)); &dep_fmri_str,
&fmri,
"depend",
"fmri",
&dep_fmri_str,
Some(attrs.clone()),
);
index.add_term(
dep_fmri.stem(),
&fmri,
"depend",
"fmri",
&dep_fmri_str,
Some(attrs),
);
} }
} }
} }
@ -3101,10 +3245,13 @@ impl FileBackend {
let entries = index.search(query, case_sensitive, limit); let entries = index.search(query, case_sensitive, limit);
results.extend(entries); results.extend(entries);
} else { } else {
debug!("No search index found for publisher: {}, falling back to simple listing", pub_name); debug!(
"No search index found for publisher: {}, falling back to simple listing",
pub_name
);
// Fallback: list packages and convert to basic IndexEntries // Fallback: list packages and convert to basic IndexEntries
let all_packages = self.list_packages(Some(&pub_name), None)?; let all_packages = self.list_packages(Some(&pub_name), None)?;
let matching_packages: Vec<IndexEntry> = all_packages let matching_packages: Vec<IndexEntry> = all_packages
.into_iter() .into_iter()
.filter(|pkg| pkg.fmri.stem().contains(query)) .filter(|pkg| pkg.fmri.stem().contains(query))
.map(|pkg| { .map(|pkg| {

View file

@ -3,5 +3,5 @@ pub mod file;
pub mod info; pub mod info;
pub mod manifest; pub mod manifest;
pub mod publisher; pub mod publisher;
pub mod versions;
pub mod search; pub mod search;
pub mod versions;

View file

@ -8,13 +8,13 @@ pub async fn get_search_v0(
State(repo): State<Arc<DepotRepo>>, State(repo): State<Arc<DepotRepo>>,
Path((publisher, token)): Path<(String, String)>, Path((publisher, token)): Path<(String, String)>,
) -> Result<Response, DepotError> { ) -> Result<Response, DepotError> {
// Decode the token (it might be URL encoded in the path, but axum usually decodes path params? // Decode the token (it might be URL encoded in the path, but axum usually decodes path params?
// Actually, axum decodes percent-encoded path segments automatically if typed as String? // Actually, axum decodes percent-encoded path segments automatically if typed as String?
// Let's assume yes or use it as is. // Let's assume yes or use it as is.
// However, typical search tokens might contain chars that need decoding. // However, typical search tokens might contain chars that need decoding.
// If standard axum decoding is not enough, we might need manual decoding. // If standard axum decoding is not enough, we might need manual decoding.
// But let's start with standard. // But let's start with standard.
// Call search // Call search
let results = repo.search(Some(&publisher), &token, false)?; let results = repo.search(Some(&publisher), &token, false)?;
@ -27,11 +27,7 @@ pub async fn get_search_v0(
)); ));
} }
Ok(( Ok(([(axum::http::header::CONTENT_TYPE, "text/plain")], body).into_response())
[(axum::http::header::CONTENT_TYPE, "text/plain")],
body,
)
.into_response())
} }
pub async fn get_search_v1( pub async fn get_search_v1(
@ -81,23 +77,28 @@ pub async fn get_search_v1(
fn split_v1_token(token: &str) -> Option<(&str, &str)> { fn split_v1_token(token: &str) -> Option<(&str, &str)> {
// Try to find the 4th underscore // Try to find the 4th underscore
let mut parts = token.splitn(5, '_'); let mut parts = token.splitn(5, '_');
if let (Some(_), Some(_), Some(_), Some(_), Some(_)) = (parts.next(), parts.next(), parts.next(), parts.next(), parts.next()) { if let (Some(_), Some(_), Some(_), Some(_), Some(_)) = (
// We found 4 parts and a remainder. parts.next(),
parts.next(),
parts.next(),
parts.next(),
parts.next(),
) {
// We found 4 parts and a remainder.
// We need to reconstruct where the split happened to return slices // We need to reconstruct where the split happened to return slices
// Actually, splitn(5) returns 5 parts. The last part is the remainder. // Actually, splitn(5) returns 5 parts. The last part is the remainder.
// But we want to be careful about the length of the prefix. // But we want to be careful about the length of the prefix.
// Let's iterate chars to find 4th underscore // Let's iterate chars to find 4th underscore
let mut underscore_count = 0; let mut underscore_count = 0;
for (i, c) in token.chars().enumerate() { for (i, c) in token.chars().enumerate() {
if c == '_' { if c == '_' {
underscore_count += 1; underscore_count += 1;
if underscore_count == 4 { if underscore_count == 4 {
return Some((&token[..i], &token[i+1..])); return Some((&token[..i], &token[i + 1..]));
} }
} }
} }
} }
None None
} }

View file

@ -1,7 +1,7 @@
use crate::config::Config; use crate::config::Config;
use crate::errors::{DepotError, Result}; use crate::errors::{DepotError, Result};
use libips::fmri::Fmri; use libips::fmri::Fmri;
use libips::repository::{FileBackend, ReadableRepository, IndexEntry}; use libips::repository::{FileBackend, IndexEntry, ReadableRepository};
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Mutex; use std::sync::Mutex;
@ -23,7 +23,12 @@ impl DepotRepo {
}) })
} }
pub fn search(&self, publisher: Option<&str>, query: &str, case_sensitive: bool) -> Result<Vec<IndexEntry>> { pub fn search(
&self,
publisher: Option<&str>,
query: &str,
case_sensitive: bool,
) -> Result<Vec<IndexEntry>> {
let backend = self let backend = self
.backend .backend
.lock() .lock()

View file

@ -375,9 +375,13 @@ async fn test_file_url_without_algo() {
// Expected format: /{publisher}/file/1/{hash} // Expected format: /{publisher}/file/1/{hash}
let url = format!("{}/test/file/1/{}", base_url, hash); let url = format!("{}/test/file/1/{}", base_url, hash);
println!("Requesting: {}", url); println!("Requesting: {}", url);
let resp = client.get(&url).send().await.unwrap(); let resp = client.get(&url).send().await.unwrap();
assert_eq!(resp.status(), 200, "Should handle file URL without algorithm"); assert_eq!(
resp.status(),
200,
"Should handle file URL without algorithm"
);
let _content = resp.text().await.unwrap(); let _content = resp.text().await.unwrap();
} }