use anyhow::Result; use log::info; use once_cell::sync::OnceCell; use reqwest::Client; use term_table::{Table, TableBuilder, TableStyle}; use tokio::process::Command; use crate::api::{CatsResp, Meme, MemesResp}; // cached api responses static CATS: OnceCell> = OnceCell::new(); static MEMES: OnceCell> = OnceCell::new(); pub async fn open_link(url: &str) -> anyhow::Result<()> { match std::env::var_os("BROWSER") { Some(browser) => { Command::new(&browser).arg(url).status().await?; }, None => opener::open(&url)?, } Ok(()) } pub async fn cats(http: &Client) -> Result<&Vec> { Ok(match CATS.get() { None => { info!("Requesting categories from server"); let res = http .get("https://data.tilera.xyz/api/jensmemes/categories") .send() .await?; let cats = serde_json::from_slice::(&res.bytes().await?)?; CATS.get_or_init(|| cats.categories.into_iter().map(|c| c.id).collect()) }, Some(x) => x, }) } pub async fn memes(http: &Client) -> Result<&Vec> { Ok(match MEMES.get() { None => { info!("Requesting memes from server"); let res = http .get("https://data.tilera.xyz/api/jensmemes/memes") .send() .await?; let memes = serde_json::from_slice::(&res.bytes().await?)?; MEMES.get_or_init(|| memes.memes) }, Some(x) => x, }) } /// returns an empty table with the correct format settings for lists pub fn list_table<'a>() -> Table<'a> { TableBuilder::new() .style(TableStyle::simple()) .separate_rows(false) .has_top_boarder(false) .has_bottom_boarder(false) .build() }