jensmemesclient/cli/src/commands/search.rs
LordMZTE 3c395a34a7
All checks were successful
continuous-integration/drone/push Build is passing
refactors and add timestamp to meme display
2021-05-12 20:13:06 +02:00

81 lines
2 KiB
Rust

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<String>,
category: Option<String>,
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(())
}