+ Adding list_channel handler
More agressive channel caching may be required here but it works as an MVP for now * Switch to hashmap for container of channel caches instead of vector This should help with cache accesses as we don't have to iterate anymore Also it makes data fetches much cleaner/shorthanded * net::list_channels has its own private structure for collecting channels vector This is basically required and is in the scope of the func itsefl to not pollute any other namespaces
This commit is contained in:
parent
8be5547d9e
commit
704f372c3e
@ -30,7 +30,7 @@ struct ServerCache {
|
||||
// container for the relevant user/serer meta data
|
||||
// We use both parts in order to to maintain jwt's within the cache
|
||||
meta: ServerConfig,
|
||||
channels: Vec<ChannelCache>
|
||||
channels: HashMap<u64, ChannelCache> // channel_id -> cache
|
||||
}
|
||||
|
||||
pub struct Cache {
|
||||
@ -41,7 +41,7 @@ pub struct Cache {
|
||||
}
|
||||
|
||||
impl ServerCache {
|
||||
pub fn from(meta: ServerConfig, channels: Vec<ChannelCache>) -> Self {
|
||||
pub fn from(meta: ServerConfig, channels: HashMap<u64, ChannelCache>) -> Self {
|
||||
ServerCache { meta, channels }
|
||||
}
|
||||
}
|
||||
@ -50,7 +50,7 @@ impl Cache {
|
||||
pub fn from(config: &ConfigFile) -> Cache {
|
||||
let mut servers = HashMap::new();
|
||||
for servercfg in &config.servers {
|
||||
let i_server_cache = ServerCache::from(servercfg.clone(), Vec::new());
|
||||
let i_server_cache = ServerCache::from(servercfg.clone(), HashMap::new());
|
||||
let url = i_server_cache.meta.server.url.clone();
|
||||
servers.insert(url, i_server_cache);
|
||||
}
|
||||
@ -83,14 +83,18 @@ impl Cache {
|
||||
let secret = &meta.meta.user.secret;
|
||||
found = match net::login(url, id, secret).await {
|
||||
Ok(jwt) => {
|
||||
let twt = jwt.clone();
|
||||
meta.meta.user.jwt = Some(jwt);
|
||||
self.active_server = Some(meta.meta.clone());
|
||||
// Setup websocket to server or something idk
|
||||
// TODO: Setup websocket to server or something idk
|
||||
self.active_text = None;
|
||||
true
|
||||
},
|
||||
Err(e) => { // TODO: some kind of logging here
|
||||
err_msg = format!("{}", e);
|
||||
Err(e) => {
|
||||
err_msg = match e.is_status() {
|
||||
true => format!("{:?}", e.status().unwrap()),
|
||||
false => format!("Issue connecting to server")
|
||||
};
|
||||
meta.meta.user.jwt = None;
|
||||
false
|
||||
}
|
||||
@ -123,25 +127,30 @@ impl Cache {
|
||||
Command::Text(hosts)
|
||||
}
|
||||
|
||||
pub fn list_channels(&self) -> Command {
|
||||
use crate::api_types;
|
||||
if let Some(serv) = &self.active_server {
|
||||
// Find the server we're whose channels we want
|
||||
let (_, cache) = self.servers.iter()
|
||||
.find(|(url, _)| url == &&serv.server.url).unwrap();
|
||||
|
||||
let mut buffer = String::from("! Channels ");
|
||||
for (i, chan) in cache.channels.iter().enumerate() {
|
||||
// NOTE only list out text channels for now
|
||||
// another command will be provided for voice channels later
|
||||
if chan.meta.r#type == api_types::TEXT_CHANNEL {
|
||||
buffer.push_str(&format!("[{}] {}, ", i, chan.meta.r#type));
|
||||
pub async fn list_channels(&mut self) -> Command {
|
||||
if let None = self.active_server {
|
||||
return Command::Failure("No active server".into())
|
||||
}
|
||||
// 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()))
|
||||
}
|
||||
|
||||
Command::Text(buffer)
|
||||
} else {
|
||||
Command::Failure(format!("No active server"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
Command::Server(host) => app.cache.switch_server(&host).await,
|
||||
Command::Message(msg) => app.cache.send_message(&msg).await,
|
||||
Command::ListHost => app.cache.list_hosts(),
|
||||
Command::ListChannel => app.cache.list_channels(),
|
||||
Command::ListChannel => app.cache.list_channels().await,
|
||||
_ => cmd
|
||||
});
|
||||
}
|
||||
|
@ -1,19 +1,38 @@
|
||||
use crate::api_types::Channel;
|
||||
use crate::api_types::Jwt;
|
||||
use serde::Deserialize;
|
||||
use crate::api_types::{Jwt, Channel, TEXT_CHANNEL};
|
||||
use reqwest::{Client, Url};
|
||||
use reqwest::Result as HttpResult;
|
||||
|
||||
// TODO: Url generation is kinda gross looking but i'm not 100%
|
||||
// convinced it needs to be pretty if its just going to add overhead
|
||||
|
||||
pub async fn login(url: &str, id: u64, secret: &str) -> HttpResult<String> {
|
||||
let client = Client::new();
|
||||
let mut url = Url::parse(&format!("{}/login", url)).unwrap();
|
||||
url.query_pairs_mut().append_pair("id", &format!("{}", id));
|
||||
url.query_pairs_mut().append_pair("secret", secret);
|
||||
let url = Url::parse_with_params(
|
||||
&format!("{}/login", url),
|
||||
&[("id", format!("{}", id).as_str()), ("secret", secret)]
|
||||
).unwrap();
|
||||
|
||||
|
||||
let response: Jwt = client.get(url).send().await?.json().await?;
|
||||
Ok(response.jwt)
|
||||
}
|
||||
|
||||
fn list_channels(url: &str, id: u64, secret: &str) -> Vec<Channel> {
|
||||
todo!()
|
||||
pub async fn list_channels(url: &str, id: u64, jwt: &str) -> HttpResult<Vec<Channel>> {
|
||||
let client = Client::new();
|
||||
let url = Url::parse_with_params(
|
||||
&format!("{}/channels/list", url),
|
||||
&[
|
||||
("id", format!("{}", id).as_str()),
|
||||
("jwt", jwt),
|
||||
("kind", format!("{}", TEXT_CHANNEL).as_str())
|
||||
]
|
||||
).unwrap();
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ChannelResponse {
|
||||
pub channels: Vec<Channel>
|
||||
}
|
||||
let response: ChannelResponse = client.get(url).send().await?.json().await?;
|
||||
Ok(response.channels)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user