use std::io; use std::io::BufRead; use std::sync::Arc; use std::time::Duration; use std::time::Instant; use colored::*; use salrucc::Cache; use salrucc::CacheClock; use salrucc::RetrievalResult; #[derive(Clone)] struct Item { pub data: String, } async fn retrieve(url: &str) -> reqwest::Result> { println!("...cache miss; invoking reqwest for {}", url.underline()); let resp = reqwest::get(url).await?; let data = resp.text().await?; let footprint = data.len(); let retrieval_result = RetrievalResult { value: Item { data }, footprint, ultimate_expiry: None, stale_expiry: None, }; Ok(retrieval_result) } struct InstantClock {} impl CacheClock for InstantClock { type Duration = Duration; type Instant = Instant; fn now(&self) -> Instant { Instant::now() } } #[tokio::main(flavor = "current_thread")] async fn main() { let cache = Cache::, _>::new(InstantClock {}, 10000000); let stdin = io::stdin(); for line in stdin.lock().lines() { let unwrapped_line = line.unwrap(); let url = unwrapped_line.trim(); if !url.is_empty() { println!("Retrieving from {}...", url.underline()); let result = cache .get_or_insert_with(&url[..], async { retrieve(&url).await }) .await; match result { Ok(x) => { println!( "...retrieval succeeded; returned {} characters", x.data.len() ); } Err(e) => { println!("...ERROR: {}", format!("{}", e).red()); } }; } } }