The world's most clever kitty cat
1use std::sync::{Arc, atomic::Ordering};
2
3use twilight_interactions::command::{CommandModel, CreateCommand};
4use twilight_model::{
5 application::interaction::{Interaction, application_command::CommandData},
6 channel::Attachment,
7};
8
9use crate::{
10 BROTLI_BUF_SIZE, BotContext, brain::Brain, cmd::DEFER_INTER_RESP_EPHEMERAL, prelude::*,
11 require_owner, status::update_status,
12};
13
14#[derive(CommandModel, CreateCommand)]
15#[command(name = "load_chain", desc = "Load a chain from a .msgpackz file")]
16pub struct LoadChainCommand {
17 /// Brain file to load
18 file: Attachment,
19 /// Use a Nushell (Legacy) compatible msgpack
20 compat: Option<bool>,
21}
22
23impl LoadChainCommand {
24 pub async fn handle(inter: Interaction, data: CommandData, ctx: Arc<BotContext>) -> Result {
25 let client = ctx.http.interaction(ctx.app_id);
26
27 require_owner!(inter, ctx, client);
28
29 let Self { file, compat } =
30 Self::from_interaction(data.into()).context("Failed to parse command data")?;
31
32 client
33 .create_response(inter.id, &inter.token, &DEFER_INTER_RESP_EPHEMERAL)
34 .await
35 .context("Failed to defer")?;
36
37 let mut data = std::io::Cursor::new(
38 reqwest::get(file.url)
39 .await
40 .context("Failed to request attachment")?
41 .bytes()
42 .await
43 .context("Failed to decode as bytes")?,
44 );
45 let mut brotli_stream = brotli::Decompressor::new(&mut data, BROTLI_BUF_SIZE);
46
47 let new_brain: Brain = if compat.unwrap_or_default() {
48 Brain::from_legacy_hashmap(
49 rmp_serde::from_read(&mut brotli_stream).context("Failed to decode brain file")?,
50 )
51 } else {
52 rmp_serde::from_read(&mut brotli_stream).context("Failed to decode brain file")?
53 };
54
55 {
56 let mut brain = ctx.brain_handle.write().await;
57 brain.merge_from(new_brain);
58 ctx.pending_save.store(true, Ordering::Relaxed);
59 update_status(&brain, &ctx.shard_sender).context("Failed to update status")?;
60 }
61
62 client
63 .update_response(&inter.token)
64 .content(Some("Bingus Learned!"))
65 .await
66 .context("Failed to send brain")?;
67
68 Ok(())
69 }
70}