use anyhow::{Context, Result}; use log::info; use reqwest::Client; use std::io::Write; use crate::table::{self, IntoTableRow}; use jm_client_core::util::{self, api}; pub async fn run( http: &Client, query: String, user: Option, category: Option, firsturl: bool, cat: bool, ) -> Result<()> { let (memes, ..) = tokio::try_join!( api::memes( http, category.as_ref().map(String::clone), user.as_ref().map(String::clone), ), async { if let Some(u) = user.as_ref() { util::assert_user_exists(http, u).await } else { Ok(()) } }, async { if let Some(c) = category.as_ref() { util::assert_category_exists(http, c).await } else { Ok(()) } } )?; let mut matches = vec![]; info!("Starting search with query '{}'", query); for meme in memes.iter() { let file_name = meme.file_name()?; if let Some(score) = fuzzy_matcher::clangd::fuzzy_match(file_name, &query) { info!("Found matching meme '{}' with score {}", file_name, score); matches.push((meme, score)); } } matches.sort_by(|a, b| b.1.cmp(&a.1)); let res = match (firsturl, cat) { (false, false) => { let mut table = table::list_table(); for m in matches { table.add_row(m.0.into_table_row()); } table.render().into_bytes() }, (true, _) => matches .first() .context("No matches found")? .0 .link .clone() .into_bytes(), (_, true) => { let url = &matches.first().context("No results found")?.0.link; http.get(url).send().await?.bytes().await?.to_vec() }, }; let stdout = std::io::stdout(); let mut handle = stdout.lock(); handle.write_all(&res)?; Ok(()) }