add sorting to list command

This commit is contained in:
LordMZTE 2020-12-20 20:52:22 +01:00
parent 928328a304
commit 76fb754e53
7 changed files with 85 additions and 18 deletions

View file

@ -67,7 +67,8 @@ pub struct User {
impl User {
pub fn get_id(&self) -> Option<&String> {
self.id.as_ref()
self.id
.as_ref()
.or(self.tokenhash.as_ref())
.or(self.userdir.as_ref())
}
@ -82,4 +83,3 @@ impl Into<Row<'_>> for &User {
])
}
}

View file

@ -1,16 +1,27 @@
use anyhow::Result;
use reqwest::Client;
use crate::util::{self, api};
use crate::util::{self, api, MemeSorting};
pub async fn run(http: &Client, cat: Option<String>, user: Option<String>) -> Result<()> {
pub async fn run(
http: &Client,
cat: Option<String>,
user: Option<String>,
sorting: Option<MemeSorting>,
) -> Result<()> {
let memes = api::memes(http).await?;
let memes = memes
.iter()
.into_iter()
.filter(|&m| cat.as_ref().map(|q| &m.category == q).unwrap_or(true))
.filter(|&m| user.as_ref().map(|q| &m.user == q).unwrap_or(true));
let mut memes = memes.collect::<Vec<_>>();
if let Some(s) = sorting {
s.sort_with(&mut memes);
}
let mut table = util::list_table();
for m in memes {

View file

@ -2,4 +2,3 @@ pub mod list;
pub mod search;
pub mod up;
pub mod users;

View file

@ -9,7 +9,7 @@ use tokio::{fs::File, io::reader_stream};
use crate::{
api::UpResp,
util::{open_link, api},
util::{api, open_link},
};
pub async fn run(

View file

@ -1,6 +1,6 @@
use reqwest::Client;
use anyhow::Result;
use crate::util::{self, api};
use anyhow::Result;
use reqwest::Client;
pub async fn run(http: &Client) -> Result<()> {
let users = api::users(http).await?;

View file

@ -1,3 +1,4 @@
use crate::util::MemeSorting;
use anyhow::Result;
use reqwest::Client;
use structopt::StructOpt;
@ -52,6 +53,13 @@ enum Cmd {
#[structopt(long, short, help = "filter by user")]
user: Option<String>,
#[structopt(
long,
short,
help = "how to sort the results. can be id, user, category or link"
)]
sort: Option<MemeSorting>,
},
#[structopt(about = "Lists all users")]
@ -81,7 +89,11 @@ async fn main() -> Result<()> {
.iter()
.for_each(|c| println!("{}", c)),
Cmd::Search { query } => commands::search::run(&http, query).await?,
Cmd::List { category, user } => commands::list::run(&http, category, user).await?,
Cmd::List {
category,
user,
sort,
} => commands::list::run(&http, category, user, sort).await?,
Cmd::Users => commands::users::run(&http).await?,
}

View file

@ -1,3 +1,6 @@
use crate::api::Meme;
use anyhow::bail;
use std::str::FromStr;
use term_table::{Table, TableBuilder, TableStyle};
use tokio::process::Command;
@ -9,18 +12,18 @@ macro_rules! init_once_cell {
None => {
let x = $init_fn;
$cell.get_or_init(|| x)
}
},
}
}
};
}
/// ways to communicyte with the JM API
pub mod api {
use once_cell::sync::OnceCell;
use log::info;
use crate::api::{Meme, CatsResp, MemesResp, User, UsersResp};
use reqwest::Client;
use crate::api::{CatsResp, Meme, MemesResp, User, UsersResp};
use anyhow::Result;
use log::info;
use once_cell::sync::OnceCell;
use reqwest::Client;
// cached api responses
static CATS: OnceCell<Vec<String>> = OnceCell::new();
@ -47,7 +50,7 @@ pub mod api {
.send()
.await?;
let memes = serde_json::from_slice::<MemesResp>(&res.bytes().await?)?;
memes.memes
}))
}
@ -55,7 +58,10 @@ pub mod api {
pub async fn users(http: &Client) -> Result<&Vec<User>> {
Ok(init_once_cell!(USERS, {
info!("Requesting users from server");
let res = http.get("https://data.tilera.xyz/api/jensmemes/users").send().await?;
let res = http
.get("https://data.tilera.xyz/api/jensmemes/users")
.send()
.await?;
let users = serde_json::from_slice::<UsersResp>(&res.bytes().await?)?;
users.users
}))
@ -82,3 +88,42 @@ pub fn list_table<'a>() -> Table<'a> {
.has_bottom_boarder(false)
.build()
}
pub enum MemeSorting {
Id,
Link,
Category,
User,
}
impl MemeSorting {
pub fn sort_with(&self, memes: &mut [&Meme]) {
macro_rules! sort {
($list:ident, $field:ident) => {
$list.sort_by(|a, b| a.$field.to_ascii_lowercase().cmp(&b.$field.to_ascii_lowercase()));
};
}
match self {
Self::Id => sort!(memes, id),
Self::Link => sort!(memes, link),
Self::Category => sort!(memes, category),
Self::User => sort!(memes, user),
}
}
}
impl FromStr for MemeSorting {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_ref() {
"id" => Ok(Self::Id),
"link" => Ok(Self::Link),
"category" => Ok(Self::Category),
"user" => Ok(Self::User),
_ => bail!("Invalid Meme sorting! options are id, link, category and user!"),
}
}
}