use serenity::client::Client; use serenity::framework::standard::{ StandardFramework, CommandResult, macros::{ command, group } }; use rusqlite::ToSql; use rusqlite::{Connection, NO_PARAMS}; group!({ name: "general", options: {}, commands: [hello, add, pull], }); use std::env; use serenity::{ model::{channel::Message, gateway::Ready}, prelude::*, }; #[derive(Debug)] struct Question { // structure for questions id: i32, question: String, } struct Base { connection: Connection, } struct Handler; impl EventHandler for Handler { // Set a handler to be called on the `ready` event. This is called when a // shard is booted, and a READY payload is sent by Discord. This payload // contains data like the current user's guild Ids, current user data, // private channels, and more. // // In this case, just print what the current user's username is. fn ready(&self, _: Context, ready: Ready) { println!("{} is connected!", ready.user.name); } } fn make_base_from_args(num: usize) -> Base { let args: Vec<_> = env::args().collect(); Base { connection: Connection::open(&args[num]).expect("Failed to open database..."), } } fn main() { // get token from args let args: Vec<_> = env::args().collect(); if args.len() < 3 && args[1] != "create" { println!("Please enter a database and token"); std::process::exit(0); } if args[1] == "create" { println!("Creating table...\n\n"); println!("Connecting to database"); let base = make_base_from_args(2); base.connection.execute( "CREATE TABLE question ( id INTEGER PRIMARY KEY, question TEXT NOT NULL )", NO_PARAMS, ).expect("Failed to create table..."); println!("Done!"); std::process::exit(0); } let token = &args[2]; let mut client = Client::new(token, Handler) .expect("Error creating client"); client.with_framework(StandardFramework::new() .configure(|c| c.prefix("fishy ")) // set the bot's prefix .group(&GENERAL_GROUP)); println!("Starting client..."); // start listening for events by starting a single shard if let Err(why) = client.start() { println!("An error occurred while running the client: {:?}", why); } } #[command] fn hello(ctx: &mut Context, msg: &Message) -> CommandResult { println!("Executing command HELLO as \"{}\"", msg.content); msg.reply(ctx, "Hello!")?; Ok(()) } #[command] fn add(ctx: &mut Context, msg: &Message) -> CommandResult { println!("Executing command ADD as \"{}\"", msg.content); let split: Vec<&str> = msg.content.split(" ").collect(); if split.len() < 3 { msg.reply(ctx, "Please add a message!")?; return Ok(()); } let addition = format!("{}", &split[2..].join(" ")); let new = Question { id: 0, question: addition, }; let base = make_base_from_args(1); println!("\tOpened connection"); print!("\tExecuting insert..."); base.connection.execute( "INSERT INTO question VALUES (?1, ?2)", &[&new.id, &new.question as &ToSql], ).expect("Failed to insert values..."); println!("OK"); msg.reply(ctx, "Added question!")?; Ok(()) } #[command] fn pull(ctx: &mut Context, msg: &Message) -> CommandResult { println!("Executing command PULL as \"{}\"", msg.content); let base = make_base_from_args(1); println!("\tOpened connection"); let mut stmt = base.connection .prepare("SELECT id, question FROM question").expect("Failed to select from database"); let qs: Vec<_> = stmt .query_map(NO_PARAMS, |row| Ok(Question { id: row.get(0).expect("Failed to get row..."), question: row.get(1).expect("Failed to get row..."), })).expect("Failed to create a map").collect(); println!("\tSuccessfully created map"); msg.reply(ctx, format!("{:?}", &qs[qs.len() - 1]))?; Ok(()) }