Add event return type

This commit is contained in:
Tobias Reisinger 2024-03-05 00:24:15 +01:00
parent 6a0e2fd7d1
commit 2c0a8ab616
Signed by: serguzim
GPG key ID: 13AD60C237A28DFE
7 changed files with 166 additions and 15 deletions

2
Cargo.lock generated
View file

@ -139,7 +139,7 @@ dependencies = [
[[package]]
name = "teamspeak-query-lib"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"clap",
"telnet",

View file

@ -106,4 +106,5 @@ pub fn clientupdate(connection: &mut Telnet, parameters: ParameterList) -> Resul
pub fn sendtextmessage(connection: &mut Telnet, target: SendTextMessageTarget, msg: String) -> Result<Response, String> {
let msg = String::from(Parameter::new("msg", &msg));
send_command(connection, &format!("sendtextmessage {} {}", msg, String::from(target)), false) }
send_command(connection, &format!("sendtextmessage {} {}", msg, String::from(target)), false)
}

View file

@ -49,6 +49,8 @@ fn main() {
wrappers::skip_welcome(&mut connection);
wrappers::login(&mut connection);
// You can check for the existence of subcommands, and if found use their
// matches just as you would the top level cmd
match cli {

View file

@ -81,4 +81,3 @@ impl Channel {
list_sorted
}
}

83
src/models/event.rs Normal file
View file

@ -0,0 +1,83 @@
use std::fmt::{Display, Formatter};
#[derive(Debug)]
pub enum Event {
ChannelList,
ChannelListFinished,
NotifyTalkStatusChange,
NotifyMessage,
NotifyMessageList,
NotifyComplainList,
NotifyBanList,
NotifyClientMoved,
NotifyClientLeftView,
NotifyClientEnterView,
NotifyClientPoke,
NotifyClientChatClosed,
NotifyClientChatComposing,
NotifyClientUpdated,
NotifyClientIds,
NotifyClientDBIDFromUid,
NotifyClientNameFromUid,
NotifyClientNameFromDBID,
NotifyClientUidFromClid,
NotifyConnectionInfo,
NotifyChannelCreated,
NotifyChannelEdited,
NotifyChannelDeleted,
NotifyChannelMoved,
NotifyServerEdited,
NotifyServerUpdated,
NotifyTextMessage,
NotifyCurrentServerConnectionChanged,
NotifyConnectStatusChange,
}
impl TryFrom<&str> for Event {
type Error = String;
//noinspection SpellCheckingInspection
fn try_from(event_type: &str) -> Result<Self, Self::Error> {
match event_type {
"channellist" => Ok(Event::ChannelList),
"channellistfinished" => Ok(Event::ChannelListFinished),
"notifytalkstatuschange" => Ok(Event::NotifyTalkStatusChange),
"notifymessage" => Ok(Event::NotifyMessage),
"notifymessagelist" => Ok(Event::NotifyMessageList),
"notifycomplainlist" => Ok(Event::NotifyComplainList),
"notifybanlist" => Ok(Event::NotifyBanList),
"notifyclientmoved" => Ok(Event::NotifyClientMoved),
"notifyclientleftview" => Ok(Event::NotifyClientLeftView),
"notifycliententerview" => Ok(Event::NotifyClientEnterView),
"notifyclientpoke" => Ok(Event::NotifyClientPoke),
"notifyclientchatclosed" => Ok(Event::NotifyClientChatClosed),
"notifyclientchatcomposing" => Ok(Event::NotifyClientChatComposing),
"notifyclientupdated" => Ok(Event::NotifyClientUpdated),
"notifyclientids" => Ok(Event::NotifyClientIds),
"notifyclientdbidfromuid" => Ok(Event::NotifyClientDBIDFromUid),
"notifyclientnamefromuid" => Ok(Event::NotifyClientNameFromUid),
"notifyclientnamefromdbid" => Ok(Event::NotifyClientNameFromDBID),
"notifyclientuidfromclid" => Ok(Event::NotifyClientUidFromClid),
"notifyconnectioninfo" => Ok(Event::NotifyConnectionInfo),
"notifychannelcreated" => Ok(Event::NotifyChannelCreated),
"notifychanneledited" => Ok(Event::NotifyChannelEdited),
"notifychanneldeleted" => Ok(Event::NotifyChannelDeleted),
"notifychannelmoved" => Ok(Event::NotifyChannelMoved),
"notifyserveredited" => Ok(Event::NotifyServerEdited),
"notifyserverupdated" => Ok(Event::NotifyServerUpdated),
"notifytextmessage" => Ok(Event::NotifyTextMessage),
"notifycurrentserverconnectionchanged" => {
Ok(Event::NotifyCurrentServerConnectionChanged)
}
"notifyconnectstatuschange" => Ok(Event::NotifyConnectStatusChange),
_ => Err(String::from("Unknown event type.")),
}
}
}
impl Display for Event {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}

View file

@ -1,5 +1,7 @@
mod channel;
mod client;
mod event;
pub use channel::Channel;
pub use client::Client;
pub use client::Client;
pub use event::Event;

View file

@ -1,4 +1,5 @@
use std::fmt::{Debug, Display, Formatter};
use crate::models::Event;
use crate::parameter::*;
@ -6,6 +7,14 @@ pub enum Response {
Ok,
Data(ParameterList),
DataList(Vec<ParameterList>),
Event(Event, ParameterList),
}
pub enum ResponseType {
Error,
Event(Event),
Data,
Unknown,
}
pub struct ResponseError {
@ -13,23 +22,66 @@ pub struct ResponseError {
pub msg: String,
}
fn split_type_and_params(response_str: &str) -> Result<(ResponseType, &str), String> {
if let Some(first_space) = response_str.find(' ') {
if let Some(first_equal) = response_str.find('=') {
if first_equal > first_space {
// The first word is not a parameter. Error or Event?
let (type_str, params) = response_str.split_once(' ').unwrap(); // We found a space, so this is safe.
let response_type = get_response_type(type_str)?;
return Ok((response_type, params));
}
}
}
Ok((ResponseType::Data, response_str))
}
fn get_response_type(type_str: &str) -> Result<ResponseType, String> {
if type_str == "error" {
return Ok(ResponseType::Error);
}
if type_str.starts_with("notify") || type_str == "channellist" || type_str == "channellistfinished" {
let event_type = Event::try_from(type_str)?;
return Ok(ResponseType::Event(event_type));
}
return Ok(ResponseType::Unknown);
}
impl TryFrom<String> for Response {
type Error = ResponseError;
fn try_from(response_str: String) -> Result<Self, ResponseError> {
let mut response_str = response_str.trim_end_matches("\n\r");
let response_str = response_str.trim_end_matches("\n\r");
if response_str.starts_with("error ") {
response_str = response_str.trim_start_matches("error ");
let response_params = parameter_parse(response_str);
Err(ResponseError::create_error(&response_params))
} else {
let mut parameter_lists: Vec<ParameterList> = Vec::new();
for response_entry in response_str.split('|') {
let response_params = parameter_parse(response_entry);
parameter_lists.push(response_params);
let (rsp_type, rsp_params) = split_type_and_params(&response_str)
.map_err(|err| ResponseError {
id: -1,
msg: err,
})?;
let mut parameter_lists: Vec<ParameterList> = Vec::new();
for response_entry in rsp_params.split('|') {
let response_params = parameter_parse(response_entry);
parameter_lists.push(response_params);
}
return match rsp_type {
ResponseType::Error => {
Err(ResponseError::create_error(&parameter_lists[0]))
}
ResponseType::Event(event_type) => {
Ok(Response::Event(event_type, parameter_lists[0].clone()))
}
ResponseType::Data => {
Ok(Response::DataList(parameter_lists))
}
ResponseType::Unknown => {
Err(ResponseError {
id: -1,
msg: "Unknown response type.".to_string(),
})
}
Ok(Response::DataList(parameter_lists))
}
}
}
@ -52,6 +104,11 @@ impl Debug for Response {
}
Ok(())
}
Response::Event(event, params) => {
write!(f, "Event: {:?}", event)?;
write!(f, "{:?};", params)?;
Ok(())
}
}
}
}
@ -78,6 +135,13 @@ impl Display for Response {
}
Ok(())
}
Response::Event(event, params) => {
write!(f, "Event: {}", event)?;
for param in params {
write!(f, "{};", param)?;
}
Ok(())
}
}
}
}