Breaks bc Command
trait can't be made into an object
This commit is contained in:
commit
3826ada069
3 changed files with 173 additions and 0 deletions
110
src/bot.rs
Normal file
110
src/bot.rs
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use crate::command::Command;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use tokio::sync::mpsc::UnboundedReceiver;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use twitch_irc::{
|
||||||
|
ClientConfig,
|
||||||
|
SecureTCPTransport,
|
||||||
|
TwitchIRCClient,
|
||||||
|
login::StaticLoginCredentials,
|
||||||
|
message::ServerMessage,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type IncomingMessages = UnboundedReceiver<ServerMessage>;
|
||||||
|
pub type Client = TwitchIRCClient<SecureTCPTransport, StaticLoginCredentials>;
|
||||||
|
/// rename types wrapped in `Arc<Mutex<...>>` to their respective name ending with `AM`
|
||||||
|
/// so if you have a type `Anatole` for example wrapped, call it `AnatoleAM` FeelsDankMan
|
||||||
|
pub type ClientAM = Arc<Mutex<Client>>;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Bot<'a, P> {
|
||||||
|
username: &'a str,
|
||||||
|
oauth_token: &'a str,
|
||||||
|
payload: Arc<Mutex<P>>,
|
||||||
|
commands: Arc<Mutex<dyn Command<CommandPayLoad=P>>>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<'a, P> Bot<'a, P>
|
||||||
|
{
|
||||||
|
/// Return a message stream and a client wrapped in `Arc<Mutex<...>>`
|
||||||
|
fn incoming_messages_and_client(&self) -> (IncomingMessages, ClientAM) {
|
||||||
|
let login = self.username.to_owned();
|
||||||
|
let oauth = self.oauth_token.to_owned();
|
||||||
|
|
||||||
|
let config = ClientConfig::new_simple(
|
||||||
|
StaticLoginCredentials::new(login, Some(oauth))
|
||||||
|
);
|
||||||
|
|
||||||
|
let (mut incoming_messages, client) =
|
||||||
|
TwitchIRCClient::<SecureTCPTransport, StaticLoginCredentials>::new(config);
|
||||||
|
|
||||||
|
let client_am = Arc::new(Mutex::new(client));
|
||||||
|
return (incoming_messages, client_am);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a `Bot` instance using the given username and oauth-token.
|
||||||
|
/// `payload` can be any type and will be wrapped to `Arc<Mutex<P>>` and passed to any command executed,
|
||||||
|
/// where the user can access the contents mutable.
|
||||||
|
pub fn new<'b>(username: &'b str, oauth_token: &'b str, payload: P) -> Bot<'a, P>
|
||||||
|
where
|
||||||
|
'b : 'a
|
||||||
|
{
|
||||||
|
Bot {
|
||||||
|
username,
|
||||||
|
oauth_token,
|
||||||
|
payload: Arc::new(Mutex::new(payload)),
|
||||||
|
commands: Arc::new(Mutex::new(HashMap::new())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn add_command(&mut self, identifier: String, command: impl Command<CommandPayLoad=P>) {
|
||||||
|
let mut commands = self.commands.lock().await;
|
||||||
|
commands.insert(identifier, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn run(&'a self) {
|
||||||
|
// set up client and message stream
|
||||||
|
let (mut incoming_messages, client_am) = self.incoming_messages_and_client();
|
||||||
|
let payload = Arc::clone(&self.payload);
|
||||||
|
let initial_channel = self.username.to_owned();
|
||||||
|
|
||||||
|
let msg_processor = tokio::spawn(async move {
|
||||||
|
{
|
||||||
|
let client = client_am.lock().await;
|
||||||
|
client.join(initial_channel).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(message) = incoming_messages.recv().await {
|
||||||
|
println!("Received message: {:?}", message);
|
||||||
|
|
||||||
|
match message {
|
||||||
|
ServerMessage::ClearChat(_) => {}
|
||||||
|
ServerMessage::ClearMsg(_) => {}
|
||||||
|
ServerMessage::GlobalUserState(_) => {}
|
||||||
|
ServerMessage::Join(_) => {}
|
||||||
|
ServerMessage::Notice(_) => {}
|
||||||
|
ServerMessage::Part(_) => {}
|
||||||
|
ServerMessage::Ping(_) => {}
|
||||||
|
ServerMessage::Pong(_) => {}
|
||||||
|
ServerMessage::Privmsg(_) => {}
|
||||||
|
ServerMessage::Reconnect(_) => {}
|
||||||
|
ServerMessage::RoomState(_) => {}
|
||||||
|
ServerMessage::UserNotice(_) => {}
|
||||||
|
ServerMessage::UserState(_) => {}
|
||||||
|
ServerMessage::Whisper(_) => {}
|
||||||
|
ServerMessage::Generic(_) => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
msg_processor.await.unwrap();
|
||||||
|
}
|
||||||
|
}
|
14
src/command.rs
Normal file
14
src/command.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
use crate::bot::ClientAM;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
|
pub trait Command {
|
||||||
|
type CommandPayLoad;
|
||||||
|
|
||||||
|
async fn execute(&self, pl_am: Arc<Mutex<Self::CommandPayLoad>>, client_am: ClientAM);
|
||||||
|
|
||||||
|
fn help(&self) -> String;
|
||||||
|
fn info(&self) -> String;
|
||||||
|
}
|
49
tests/integration_test.rs
Normal file
49
tests/integration_test.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use twitchbot_rs::{Bot, Command};
|
||||||
|
use twitchbot_rs::bot::ClientAM;
|
||||||
|
|
||||||
|
|
||||||
|
pub struct Payload {
|
||||||
|
content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// pub struct PingCommand;
|
||||||
|
//
|
||||||
|
// impl Command for PingCommand {
|
||||||
|
// type CommandPayLoad = Payload;
|
||||||
|
//
|
||||||
|
// async fn execute(&self, pl_am: Arc<Mutex<Self::CommandPayLoad>>, client_am: ClientAM) {
|
||||||
|
// let client
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn help(&self) -> String {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn info(&self) -> String {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn main() {
|
||||||
|
// let bot = Bot::new("");
|
||||||
|
let login = std::env::var("LOGIN").unwrap();
|
||||||
|
let oauth = std::env::var("OAUTH").unwrap();
|
||||||
|
let bot = Bot::new(
|
||||||
|
login.as_str(),
|
||||||
|
oauth.as_str(),
|
||||||
|
Payload { content: String::new() },
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// bot.add_command()
|
||||||
|
|
||||||
|
bot.run().await;
|
||||||
|
|
||||||
|
println!("hello world!")
|
||||||
|
}
|
Loading…
Reference in a new issue