diff --git a/src/args.rs b/src/args.rs index a21df05..be063c4 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,5 +1,6 @@ #![allow(clippy::module_name_repetitions)] +use crate::operations::SearchBy; use clap::{Parser, Subcommand, ValueHint}; #[derive(Debug, Clone, Parser)] @@ -105,6 +106,10 @@ pub struct SearchArgs { /// The string the package must match in the search #[clap(required = true)] pub search: Vec, + + /// Sets the search-by directive for searching the AUR only + #[clap(long, short, possible_values = SearchBy::variants())] + pub by: Option, } #[derive(Default, Debug, Clone, Parser)] diff --git a/src/internal/rpc.rs b/src/internal/rpc.rs index 81ca890..ebc5764 100644 --- a/src/internal/rpc.rs +++ b/src/internal/rpc.rs @@ -1,3 +1,4 @@ +use crate::operations::SearchBy; use std::sync::Arc; #[derive(serde::Deserialize, Debug, Clone)] @@ -75,7 +76,7 @@ pub fn rpcinfo(pkg: &str) -> InfoResults { } /// Return a struct of type [`SearchResults`] from the AUR. -pub fn rpcsearch(pkg: &str) -> SearchResults { +pub fn rpcsearch(pkg: &str, by: SearchBy) -> SearchResults { // Initialise TLS connector let tls_connector = Arc::new(native_tls::TlsConnector::new().unwrap()); @@ -87,8 +88,8 @@ pub fn rpcsearch(pkg: &str) -> SearchResults { // Send request and parse results into json agent .get(&format!( - "https://aur.archlinux.org/rpc/?v=5&type=search&arg={}", - pkg + "https://aur.archlinux.org/rpc/?v=5&type=search&by={}&arg={}", + by, pkg )) .call() .unwrap() diff --git a/src/main.rs b/src/main.rs index 5cc42d7..4386ec2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -214,7 +214,7 @@ fn cmd_search(args: &SearchArgs, options: Options) { let asp = spinner!("Searching AUR for {}", query_string); // Search AUR - let ret = operations::aur_search(&query_string, options); + let ret = operations::aur_search(&query_string, options, args.by.unwrap_or_default()); asp.stop_bold("AUR search complete"); ret diff --git a/src/operations/mod.rs b/src/operations/mod.rs index ef348bb..0843999 100644 --- a/src/operations/mod.rs +++ b/src/operations/mod.rs @@ -1,7 +1,7 @@ pub use aur_install::*; pub use clean::*; pub use install::*; -pub use search::{aur_search, repo_search as search}; +pub use search::{aur_search, repo_search as search, SearchBy}; pub use uninstall::*; pub use upgrade::*; diff --git a/src/operations/search.rs b/src/operations/search.rs index d1f9dee..35865be 100644 --- a/src/operations/search.rs +++ b/src/operations/search.rs @@ -2,17 +2,82 @@ use chrono::{Local, TimeZone}; use colored::Colorize; use textwrap::wrap; +use std::fmt::Display; +use std::str::FromStr; + use crate::internal::commands::ShellCommand; use crate::internal::error::SilentUnwrap; use crate::internal::exit_code::AppExitCode; use crate::internal::rpc::rpcsearch; use crate::{log, Options}; +#[allow(clippy::module_name_repetitions)] +#[derive(Debug, Clone, Copy)] +pub enum SearchBy { + Name, + NameDesc, + Maintainer, + Depends, + MakeDepends, + OptDepends, + CheckDepends, +} + +impl FromStr for SearchBy { + type Err = String; + fn from_str(s: &str) -> Result { + match s { + "name" => Ok(Self::Name), + "name-desc" => Ok(Self::NameDesc), + "maintainer" => Ok(Self::Maintainer), + "depends" => Ok(Self::Depends), + "makedepends" => Ok(Self::MakeDepends), + "optdepends" => Ok(Self::OptDepends), + "checkdepends" => Ok(Self::CheckDepends), + _ => Err(format!("Invalid search-by directive \"{}\"", s)), + } + } +} + +impl Display for SearchBy { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Name => write!(f, "name"), + Self::NameDesc => write!(f, "name-desc"), + Self::Maintainer => write!(f, "maintainer"), + Self::Depends => write!(f, "depends"), + Self::MakeDepends => write!(f, "makedepends"), + Self::OptDepends => write!(f, "optdepends"), + Self::CheckDepends => write!(f, "checkdepends"), + } + } +} + +impl Default for SearchBy { + fn default() -> Self { + Self::NameDesc + } +} + +impl SearchBy { + pub fn variants() -> Vec<&'static str> { + vec![ + "name", + "name-desc", + "maintainer", + "depends", + "makedepends", + "optdepends", + "checkdepends", + ] + } +} + #[allow(clippy::module_name_repetitions)] /// Searches for packages from the AUR and returns wrapped results -pub fn aur_search(query: &str, options: Options) -> String { +pub fn aur_search(query: &str, options: Options, by: SearchBy) -> String { // Query AUR for package info - let res = rpcsearch(query); + let res = rpcsearch(query, by); // Get verbosity let verbosity = options.verbosity;