discord-egress/src/command.rs

172 lines
6.1 KiB
Rust
Raw Normal View History

2024-07-23 17:13:07 +00:00
use std::fmt::Display;
2024-07-22 17:15:03 +00:00
use crate::Context;
2024-07-23 17:13:07 +00:00
use anyhow::Error;
use poise::serenity_prelude::{ChannelId, ChannelType, GuildChannel};
struct Server {
channels: Vec<Channel>,
orphanage: Vec<GuildChannel>,
needs_clean: bool,
}
struct Channel {
this: GuildChannel,
children: Vec<Channel>
}
impl Display for Server {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn print(f: &mut std::fmt::Formatter<'_>, tab: usize, channel: &Vec<Channel>) {
for i in channel {
for _ in 0..tab { let _ = write!(f, "\t"); }
let _ = writeln!(f, "{} {}", prefix(i.this.kind),i.this.name);
print(f, tab+1, &i.children);
}
}
fn prefix(kind: ChannelType) -> &'static str {
match kind {
poise::serenity_prelude::ChannelType::Text => "💬",
poise::serenity_prelude::ChannelType::Private => "🕵️",
poise::serenity_prelude::ChannelType::Voice => "🔊",
poise::serenity_prelude::ChannelType::GroupDm => "👨‍👦‍👦",
poise::serenity_prelude::ChannelType::Category => "📁",
poise::serenity_prelude::ChannelType::News => "📢",
poise::serenity_prelude::ChannelType::NewsThread => "📢🧵",
poise::serenity_prelude::ChannelType::PublicThread => "🧵",
poise::serenity_prelude::ChannelType::PrivateThread => "🕵️🧵",
poise::serenity_prelude::ChannelType::Stage => "🎙️",
poise::serenity_prelude::ChannelType::Directory => "📒",
poise::serenity_prelude::ChannelType::Forum => "🗣️",
_ => "?",
}
}
print(f, 0, &self.channels);
if self.needs_clean {
let _ = writeln!(f, "Orphans: (please clean() before displaying...)");
for i in &self.orphanage {
let _ = write!(f, "{} {},", prefix(i.kind),i.name);
}
}
write!(f, "")
}
}
impl Server {
fn new() -> Self {
Self {
channels: Vec::new(),
orphanage: Vec::new(),
needs_clean: false
}
}
// TODO this might be broken
fn search<'a>(target: &'a mut Vec<Channel>, find: &ChannelId) -> Option<&'a mut Channel> {
for child in target {
if child.this.id == *find {
return Some(child);
}
match Self::search(&mut child.children, find) {
Some(x) => return Some(x),
None => {},
}
}
None
}
fn add(&mut self, insert: GuildChannel) {
// make sure the new item wants a parent
if let Some(parent_id) = &insert.parent_id {
// find the parent (needs to go thru all nodes)
match Self::search(&mut self.channels, &parent_id) {
Some(parent_node) => {
parent_node.children.push(Channel { this: insert, children: Vec::new() });
},
None => {
// couldn't find parent, store somewhere else until it's parent is added...
self.orphanage.push(insert);
self.needs_clean = true;
},
}
} else {
self.channels.push(Channel { this: insert, children: Vec::new() })
}
}
fn clean(&mut self) {
if !self.needs_clean {return;}
// Look thru the orphanage and try to find parents
for orphan in &self.orphanage {
if let Some(parent_id) = orphan.parent_id {
if let Some(found) = Self::search(&mut self.channels, &parent_id) {
found.children.push(Channel { this: orphan.clone(), children: Vec::new() });
} else {
panic!("⚠️ Couldn't find parent for orphan!");
}
} else {
panic!("⚠️ All orphans should want a parent node!");
}
}
self.orphanage.clear();
self.needs_clean = false;
}
}
2024-07-22 17:15:03 +00:00
// NOTE!!! Make sure these names in quotes are lowercase!
2024-07-23 17:13:07 +00:00
#[poise::command(slash_command, rename = "index", guild_only)]
pub async fn index(ctx: Context<'_>) -> Result<(), Error> {
let guild = ctx.guild_id().unwrap().to_partial_guild(ctx.serenity_context()).await.unwrap();
match guild.channels(ctx.http()).await {
Ok(ok) => {
let mut server = Server::new();
// iterate thru all channels
ok.into_iter().for_each(|(_id, current)| {
match current.kind {
poise::serenity_prelude::ChannelType::Text => {
server.add(current);
// current.position,
},
poise::serenity_prelude::ChannelType::Private => todo!(),
poise::serenity_prelude::ChannelType::Voice => {
server.add(current);
// current.user_limit,
// current.parent_id,
},
poise::serenity_prelude::ChannelType::GroupDm => todo!(),
poise::serenity_prelude::ChannelType::Category => {
server.add(current);
},
poise::serenity_prelude::ChannelType::News => todo!(),
poise::serenity_prelude::ChannelType::NewsThread => todo!(),
poise::serenity_prelude::ChannelType::PublicThread => todo!(),
poise::serenity_prelude::ChannelType::PrivateThread => todo!(),
poise::serenity_prelude::ChannelType::Stage => todo!(),
poise::serenity_prelude::ChannelType::Directory => todo!(),
poise::serenity_prelude::ChannelType::Forum => todo!(),
poise::serenity_prelude::ChannelType::Unknown(_) => todo!(),
_ => todo!(),
}
});
server.clean();
println!("{}", server);
},
Err(_) => todo!(),
}
2024-07-22 17:15:03 +00:00
Ok(())
}