- Removing more behavior from the cache for complexity reduciton

+ Cache is no longer contained in app structure
This should let us later throw this into an Arc<Mutex<>> for better
async support.
! Also more cache access safety is being done on the front end because the cahe doesn't guarantee much on access
Perhaps some convenience wrappers would make this look nicer(with inline)

!!! Main needs a lot of flattening
It's technically not much of a problem since most of the code behind 1/2 match's
which really just bloat the hell out of indentation making it look bad when its not _that_ bad.
However it still bugs me so I should probably do something about that(also (inline))
This commit is contained in:
shockrah 2021-04-14 22:44:57 -07:00
parent 39ae3ba6be
commit 894a5bae34
4 changed files with 37 additions and 29 deletions

View File

@ -31,7 +31,7 @@ impl Message {
} }
#[derive(Deserialize, Clone)] #[derive(Debug, Deserialize, Clone)]
pub struct Channel { pub struct Channel {
pub name: String, pub name: String,
pub id: u64, pub id: u64,

View File

@ -132,30 +132,26 @@ impl Cache {
Command::Text(hosts) Command::Text(hosts)
} }
pub async fn list_channels(&mut self) -> Command { pub fn add_channels(&mut self, url: &str, channels: &[api::Channel]) {
if let None = self.active_server { // if the url isn't there we just silently fail?
return Command::Failure("No active server".into()) let serv_ref = self.servers.get_mut(url).unwrap();
for chan in channels.iter() {
let cache = ChannelCache {
meta: chan.clone(),
messages: Vec::new()
};
serv_ref.channels.insert(chan.id, cache);
} }
// we have to own our own reference here to avoid mutating after immutable borrows
let config = self.active_server.clone().unwrap();
let id = config.user.id;
let jwt = config.user.jwt.unwrap();
let url = config.server.url.as_str();
let mut buf = String::new();
match net::list_channels(url, id, jwt.as_str()).await {
Ok(mut channels) => {
for chan in channels.iter_mut() {
let id = chan.id;
let chan_cache = ChannelCache { meta: chan.clone(), messages: Vec::new() };
self.servers.get_mut(url).unwrap().channels.insert(id, chan_cache);
let chan = format!("{}: {},", id, chan.name);
buf.push_str(chan.as_str());
}
Command::Text(buf)
},
Err(e) => {
Command::Failure(format!("Couldn't fetch channels: {:?}", e.status()))
} }
pub fn session(&self) -> Option<(String, u64, String)>{
if let Some(serv) = &self.active_server {
let id = serv.user.id;
let url = serv.server.url.clone();
let jwt = serv.user.jwt.clone().unwrap_or("".to_string());
Some((url, id, jwt))
} else {
None
} }
} }
} }

View File

@ -10,7 +10,6 @@ mod net;
use crate::util::event::{Event, Events}; use crate::util::event::{Event, Events};
use crate::command::Command; use crate::command::Command;
use crate::cache::Cache; use crate::cache::Cache;
use crate::config::ConfigFile;
use std::{env, fs, error::Error, io}; use std::{env, fs, error::Error, io};
use std::sync::Mutex; use std::sync::Mutex;
use clap::{App as Clap, Arg, ArgMatches}; use clap::{App as Clap, Arg, ArgMatches};
@ -41,7 +40,7 @@ struct App {
} }
impl App { impl App {
fn new(config: &ConfigFile) -> App { fn new() -> App {
let init_commands = vec![ let init_commands = vec![
Command::Text("! /chan | /channel <u64> - Switches text context to that channel".into()), Command::Text("! /chan | /channel <u64> - Switches text context to that channel".into()),
Command::Text("! /serv | /server <hostname> - Must include port if its not default to 80/443".into()), Command::Text("! /serv | /server <hostname> - Must include port if its not default to 80/443".into()),
@ -49,7 +48,6 @@ impl App {
Command::Text("! /help - Shows the help menu".into()), Command::Text("! /help - Shows the help menu".into()),
Command::Text("! Commands: available".into()), Command::Text("! Commands: available".into()),
]; ];
let cache = Cache::from(&config);
App { App {
input: String::new(), input: String::new(),
input_mode: InputMode::Normal, input_mode: InputMode::Normal,
@ -110,7 +108,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
let mut events = Events::new(); let mut events = Events::new();
// Create default app state // Create default app state
let mut app = App::new(&config); let mut app = App::new();
let cache: Mutex<Cache> = Mutex::new(Cache::from(&config)); let cache: Mutex<Cache> = Mutex::new(Cache::from(&config));
loop { loop {
@ -243,7 +241,20 @@ async fn main() -> Result<(), Box<dyn Error>> {
}, },
Command::Message(msg) => cache.lock().unwrap().send_message(&msg).await, Command::Message(msg) => cache.lock().unwrap().send_message(&msg).await,
Command::ListHost => cache.lock().unwrap().list_hosts(), Command::ListHost => cache.lock().unwrap().list_hosts(),
Command::ListChannel => cache.lock().unwrap().list_channels().await, Command::ListChannel => {
let session_params = cache.lock().unwrap().session();
if let Some((url, id, jwt)) = session_params {
match net::list_channels(&url , id, &jwt).await {
Ok(channels) => {
cache.lock().unwrap().add_channels(&url, channels.as_slice());
Command::Text(format!("{:?}", channels))
},
Err(_) => Command::Text("Coulnd't fetch channels".into())
}
} else {
Command::Text("adf".into())
}
},
_ => cmd _ => cmd
}); });
} }

View File

@ -53,6 +53,7 @@ pub async fn send_text<'m>(url: &str, id: u64, jwt: &str, chan: u64, msg: &str)
Ok(client.post(url).body(body).headers(headers).send().await?) Ok(client.post(url).body(body).headers(headers).send().await?)
} }
#[allow(dead_code)]
pub fn ws_url(base: &str, jwt: Option<String>) -> String { pub fn ws_url(base: &str, jwt: Option<String>) -> String {
let base = format!("{}/text", base); let base = format!("{}/text", base);
let jwt = jwt.unwrap_or("hehexd".into()); let jwt = jwt.unwrap_or("hehexd".into());