aboutsummaryrefslogtreecommitdiff
path: root/src/discord.rs
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2020-11-13 15:20:09 +0100
committerDaniel Schadt <kingdread@gmx.de>2020-11-13 15:20:09 +0100
commit27e68e4b0d6b6bf3d05166e6d6a68d56ff5a0704 (patch)
treeec8446eeabc6c5d7392cae4785b6a61608c3ac19 /src/discord.rs
parent600f41c4e7e4ceaa5814554ff44abbfa18854a79 (diff)
downloadezau-27e68e4b0d6b6bf3d05166e6d6a68d56ff5a0704.tar.gz
ezau-27e68e4b0d6b6bf3d05166e6d6a68d56ff5a0704.tar.bz2
ezau-27e68e4b0d6b6bf3d05166e6d6a68d56ff5a0704.zip
update dependencies
This is a bit bigger than usual, because it brings the serenity update from 0.8.x to 0.9 with a lot of API changes. The biggest offender is the new async environment, which means that we need to sprinkle some .awaits here and there, as well as use tokio to spawn a runtime. Serenity currently uses tokio 0.2, so we need to stick to the older version until serenity updates, otherwise we'll get a runtime mismatch. Another small change comes from serenity switching to typemap_rev[1] instead of their old implementation, which is currently still missing some methods. Until those are implemented[2], we're patching the dependency directly. The good news is that all of the changes are pretty much contained to src/discord.rs only, as the other parts of ezau could stay untouched. [1]: https://github.com/bdashore3/typemap_rev [2]: https://github.com/bdashore3/typemap_rev/pull/1
Diffstat (limited to 'src/discord.rs')
-rw-r--r--src/discord.rs74
1 files changed, 46 insertions, 28 deletions
diff --git a/src/discord.rs b/src/discord.rs
index 839b1c8..976b2d6 100644
--- a/src/discord.rs
+++ b/src/discord.rs
@@ -6,6 +6,7 @@ use evtclib::{Log, Outcome};
use serenity::client::bridge::gateway::ShardManager;
use serenity::model::id::*;
use serenity::prelude::*;
+use tokio::runtime::Runtime;
use log::info;
@@ -34,61 +35,78 @@ struct Handler {
}
impl Handler {
- fn do_link_update(&self, ctx: &Context) -> Result<()> {
- let mut messages = ChannelId(self.channel_id).messages(&ctx, |r| r.limit(25))?;
+ async fn do_link_update(&self, ctx: &Context) -> Result<()> {
+ let mut messages = ChannelId(self.channel_id)
+ .messages(&ctx, |r| r.limit(25))
+ .await?;
messages.sort_by_key(|m| m.timestamp);
- messages.retain(|m| {
- m.is_own(ctx)
- && Utc::now().signed_duration_since(m.timestamp)
- < chrono::Duration::hours(MAX_HOURS)
- });
+
+ // Retain does not work with async predicates, so we have to do it the old-fashioned way.
+ // This is slower than a proper implementation because we do more element shifts than
+ // needed, but it is also the easiest way to implement it and shouldn't matter for the 25
+ // messages that we load.
+ let mut i = 0;
+ while i < messages.len() {
+ let is_good = messages[i].is_own(ctx).await
+ && Utc::now().signed_duration_since(messages[i].timestamp)
+ < chrono::Duration::hours(MAX_HOURS);
+ if is_good {
+ i += 1;
+ } else {
+ messages.remove(i);
+ }
+ }
if let Some(mut m) = messages.pop() {
let new_text = insert_link(&m.content, &self.log, &self.link);
if new_text.len() <= MAX_MESSAGE_LENGTH {
- m.edit(ctx, |m| m.content(new_text))?;
+ m.edit(ctx, |m| m.content(new_text)).await?;
return Ok(());
}
}
let new_text = insert_link("", &self.log, &self.link);
- ChannelId(self.channel_id).say(ctx, new_text)?;
+ ChannelId(self.channel_id).say(ctx, new_text).await?;
Ok(())
}
}
+#[serenity::async_trait]
impl EventHandler for Handler {
- fn ready(&self, ctx: Context, _ready: serenity::model::gateway::Ready) {
+ async fn ready(&self, ctx: Context, _ready: serenity::model::gateway::Ready) {
info!("Discord client is ready");
- let result = self.do_link_update(&ctx);
+ let result = self.do_link_update(&ctx).await;
- let mut data = ctx.data.write();
+ let mut data = ctx.data.write().await;
data.insert::<PostLinkResult>(result);
if let Some(manager) = data.get::<ShardManagerContainer>() {
- manager.lock().shutdown_all();
+ manager.lock().await.shutdown_all().await;
}
}
}
pub fn post_link(discord_token: &str, channel_id: u64, log: Log, link: String) -> Result<()> {
- let mut client = Client::new(
- discord_token,
- Handler {
- channel_id,
- log,
- link,
- },
- )?;
- {
- let mut data = client.data.write();
- data.insert::<ShardManagerContainer>(Arc::clone(&client.shard_manager));
- }
- client.start()?;
+ let mut rt = Runtime::new()?;
+
+ rt.block_on(async {
+ let mut client = Client::builder(discord_token)
+ .event_handler(Handler {
+ channel_id,
+ log,
+ link,
+ })
+ .await?;
+ {
+ let mut data = client.data.write().await;
+ data.insert::<ShardManagerContainer>(Arc::clone(&client.shard_manager));
+ }
+ client.start().await?;
- let mut data = client.data.write();
- data.remove::<PostLinkResult>().unwrap_or(Ok(()))
+ let mut data = client.data.write().await;
+ data.remove::<PostLinkResult>().unwrap_or(Ok(()))
+ })
}
fn find_insertion(text: &str, category: &str) -> Option<usize> {