manifold/src/models/fueltank.rs

116 lines
2.8 KiB
Rust
Raw Normal View History

2023-08-24 21:39:38 +00:00
use std::fmt::{Display, Formatter};
use std::fs;
use std::path::PathBuf;
use dirs::home_dir;
use std::io::{SeekFrom, Seek};
use reqwest::Client;
use reqwest::header::CONTENT_TYPE;
use crate::error::{ManifoldError, ManifoldResult};
const CACHE_VERSION: &'static str = "1";
pub trait Pump<V> {
fn pump<F>(self) -> Result<V, ManifoldError>;
}
#[derive(Copy, Clone, Debug)]
#[allow(dead_code)]
pub struct FuelTank {
mode: TankMode,
}
#[derive(Copy, Clone, Debug)]
enum TankMode {
Cache,
}
impl FuelTank {
pub fn with_cache() -> Self {
Self {
mode: TankMode::Cache,
}
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Tip {
pub number: i32,
pub tip: String,
}
impl Display for Tip {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "#{}: {}", self.number, self.tip)
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Croak {
pub tips: Vec<Tip>,
}
pub async fn croak() -> ManifoldResult<Vec<Tip>> {
debug!("Getting new tips");
let result: Croak;
let client = Client::new();
result = client.get("https://frog.tips/api/1/tips/")
.header(CONTENT_TYPE, "application/json")
.send().await.unwrap().json().await.unwrap();
debug!("Result: {:?}", &result);
Ok(result.tips)
}
impl FuelTank {
pub async fn next_or_fill(self) -> Result<Tip, ManifoldError> {
debug!("Filling tank!");
let mut cache = {
let mut path = PathBuf::new();
path.push(home_dir().ok_or(ManifoldError::from("No home dir"))?);
path.push(".local");
path.push(format!("coffeebot-frog-cache-{}.json", CACHE_VERSION));
debug!("Cache path: {:?}", &path);
fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(path)
.map_err(|e| {
error!("Error creating cache file: {}", e);
ManifoldError::from("CACHE ERROR")
})?
};
debug!("Cache: {:?}", &cache);
let json: Result<Vec<Tip>, serde_json::Error> = serde_json::from_reader(&mut cache);
debug!("Json: {:?}", &json);
let mut tips = match json {
Ok(contents) => {
match contents.len() {
0 => croak().await?,
_ => contents,
}
}
_ => croak().await?,
};
debug!("Got tips: {:?}", &tips);
let tip = tips.pop().ok_or(ManifoldError::from("FROG HAS NO TIPS FOR YOU. CROAK ERROR 12"))?;
debug!("Got single tip: {:?}", &tip);
cache
.set_len(0)
.and_then(|_| cache.seek(SeekFrom::Start(0)))?;
debug!("Writing cache");
serde_json::to_writer(cache, &tips)?;
Ok(tip)
}
}