diff options
author | Daniel Schadt <kingdread@gmx.de> | 2020-11-13 15:20:09 +0100 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2020-11-13 15:20:09 +0100 |
commit | 27e68e4b0d6b6bf3d05166e6d6a68d56ff5a0704 (patch) | |
tree | ec8446eeabc6c5d7392cae4785b6a61608c3ac19 /src/discord.rs | |
parent | 600f41c4e7e4ceaa5814554ff44abbfa18854a79 (diff) | |
download | ezau-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.rs | 74 |
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> { |