Merge pull request #7 from victormignot/connect-mongo

Add basic MongoDB connection
This commit is contained in:
Victor Mignot 2022-10-19 03:49:49 +00:00 committed by GitHub
commit c1fd41146f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 105 additions and 19 deletions

View file

@ -1,2 +1,5 @@
# Discord Token
DISCORD_TOKEN="Enter your Discord secret token"
# MongoDB connection string
MONGO_URI="Enter your Mongo connection string"

1
Cargo.lock generated
View file

@ -1857,6 +1857,7 @@ name = "yorokobot"
version = "0.1.0"
dependencies = [
"mongodb",
"serde",
"serenity",
"tokio",
]

View file

@ -9,3 +9,4 @@ edition = "2021"
serenity = { version="0.11", default-features = false, features = ["client", "gateway", "rustls_backend", "model" ] }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
mongodb = "2.3.0"
serde = { version = "1.0", features = [ "derive" ] }

11
compose.yaml Normal file
View file

@ -0,0 +1,11 @@
services:
mongodb:
image: mongo:latest
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: root
MONGO_INITDB_DATABASE: yorokobot
ports:
- 27017:27017

View file

@ -1,3 +1,8 @@
//! Module containing the Yorokobot client and used structs
use crate::errors::ClientsError;
use mongodb::{options::ClientOptions as MongoClientOptions, Client as MongoClient};
use serenity::{prelude::GatewayIntents, Client as DiscordClient};
/// Yorokobot's client.
@ -8,50 +13,89 @@ use serenity::{prelude::GatewayIntents, Client as DiscordClient};
/// # async fn run() {
/// use yorokobot::client::{Client, ClientCredentials};
///
/// let token = String::from("Your discord token");
/// let discord_token = String::from("Your discord token");
/// let mongo_uri = String::from("Your Mongo URI");
///
/// let credentials = ClientCredentials {
/// discord_token: &token,
/// discord_token: &discord_token,
/// mongo_uri: &mongo_uri,
/// };
///
/// let mut client = Client::new(credentials).await;
/// let mut client = Client::new(credentials).await.expect("Error creating client");
///
/// client.connect().await;
///
/// # }
/// ```
///
pub struct Client {
/// The Serenity Discord Client
discord_client: DiscordClient,
/// The MongoDB Client
mongodb_client: Option<MongoClient>,
/// MongoDB Client Options
mongodb_options: MongoClientOptions,
}
/// Yorokobot connection credentials
pub struct ClientCredentials<'a> {
/// Token for Discord API
pub discord_token: &'a String,
/// MongoDB connection string.
pub mongo_uri: &'a String,
}
impl<'a> Client {
/// Create a Yorokobot client
pub async fn new(credentials: ClientCredentials<'a>) -> Client {
let discord_client =
DiscordClient::builder(credentials.discord_token, GatewayIntents::empty())
.await
.expect("Could not create Discord Client");
pub async fn new(credentials: ClientCredentials<'a>) -> Result<Self, ClientsError> {
let discord_client = match DiscordClient::builder(
credentials.discord_token,
GatewayIntents::empty(),
)
.await
{
Ok(c) => c,
Err(e) => return Err(ClientsError::Discord(e)),
};
Client { discord_client }
let mongodb_options = match MongoClientOptions::parse(credentials.mongo_uri).await {
Ok(o) => o,
Err(e) => return Err(ClientsError::Database(e)),
};
Ok(Client {
discord_client,
mongodb_options,
mongodb_client: None,
})
}
/// Start connection to Discord API.
/// Wrap [`serenity::client::Client`] start method.
pub async fn connect_discord(&mut self) {
if let Err(error) = self.discord_client.start().await {
println!("Could not connect to Discord: {:?}", error);
pub async fn connect_discord(&mut self) -> Result<(), ClientsError> {
match self.discord_client.start().await {
Ok(_) => Ok(()),
Err(e) => Err(ClientsError::Discord(e)),
}
}
/// Connect to the Mongo Database
pub fn connect_mongodb(&mut self) -> Result<(), ClientsError> {
self.mongodb_client = match MongoClient::with_options(self.mongodb_options.clone()) {
Ok(c) => Some(c),
Err(e) => return Err(ClientsError::Database(e)),
};
Ok(())
}
/// Connect client to the Mongo database then to the Discord API.
pub async fn connect(&mut self) {
self.connect_discord().await;
pub async fn connect(&mut self) -> Result<(), ClientsError> {
self.connect_mongodb()?;
self.connect_discord().await?;
Ok(())
}
}

14
src/errors.rs Normal file
View file

@ -0,0 +1,14 @@
//! Common Yorokobot errors
use mongodb::error::Error as MongoError;
use serenity::prelude::SerenityError;
/// The kind of errors that can be returned by Client::new
#[derive(Debug)]
pub enum ClientsError {
/// Serenity error while building client
Discord(SerenityError),
///Mongo error while parsing options
Database(MongoError),
}

View file

@ -6,5 +6,6 @@
#![deny(missing_docs)]
#![deny(warnings)]
/// Module containing the Yorokobot client and used structs
pub mod client;
pub mod errors;

View file

@ -1,16 +1,27 @@
use std::env;
use yorokobot::client::{Client, ClientCredentials};
use yorokobot::{
client::{Client, ClientCredentials},
errors::ClientsError,
};
#[tokio::main]
async fn main() {
let discord_token = env::var("DISCORD_TOKEN").expect("Cannot fetch Discord token");
let mongodb_uri = env::var("MONGODB_URI").expect("Cannot fetch Mongo URI");
let credentials = ClientCredentials {
discord_token: &discord_token,
mongo_uri: &mongodb_uri,
};
let mut client = Client::new(credentials).await;
let mut client = Client::new(credentials)
.await
.expect("Could not create client");
client.connect_discord().await;
client.connect().await.unwrap_or_else(|error| match error {
ClientsError::Database(e) => panic!("Could not connect to database: {:?}", e),
ClientsError::Discord(e) => panic!("Could not connect to Discord: {:?}", e),
});
}