sparkle_impostor/
component.rs

1//! Handling the message having components
2
3use twilight_model::channel::message::{component::ActionRow, Component};
4
5use crate::{error::Error, MessageSource};
6
7/// Info about the message's components
8#[derive(Clone, Debug, PartialEq, Eq)]
9pub struct Info {
10    /// URL components in the message, which can be replicated
11    pub url_components: Vec<Component>,
12    /// Whether the message has components that can't be replicated
13    pub has_invalid_components: bool,
14}
15
16impl MessageSource<'_> {
17    /// Check that the message has no non-URL components
18    ///
19    /// URL components can be replicated, so they're allowed
20    ///
21    /// # Errors
22    ///
23    /// Returns [`Error::Component`] if the message has a non-URL
24    /// component
25    pub const fn check_component(&self) -> Result<(), Error> {
26        if self.component_info.has_invalid_components {
27            return Err(Error::Component);
28        }
29
30        Ok(())
31    }
32}
33
34pub(crate) fn filter_valid(components: &[Component]) -> Vec<Component> {
35    components
36        .iter()
37        .filter_map(|component| {
38            if let Component::ActionRow(action_row) = component {
39                let components_inner = action_row
40                    .components
41                    .iter()
42                    .filter(|inner_component| is_valid(inner_component))
43                    .cloned()
44                    .collect::<Vec<_>>();
45
46                if components_inner.is_empty() {
47                    None
48                } else {
49                    Some(Component::ActionRow(ActionRow {
50                        components: components_inner,
51                    }))
52                }
53            } else {
54                is_valid(component).then(|| component.clone())
55            }
56        })
57        .collect()
58}
59
60pub(crate) const fn is_valid(component: &Component) -> bool {
61    matches!(component, Component::Button(button) if button.custom_id.is_none())
62}