Skip to main content

azalea_chat/
click_event.rs

1use serde::Serialize;
2#[cfg(feature = "simdnbt")]
3use simdnbt::{
4    DeserializeError,
5    owned::{Nbt, NbtCompound},
6};
7
8#[cfg(feature = "simdnbt")]
9use crate::get_in_compound;
10
11macro_rules! define_click_event_struct {
12    (
13        $(
14            $action_name:ident : $action_variant:ident {
15                $(
16                    $(#[$meta:meta])* $field:ident : $type:ty
17                ),*
18                $(,)?
19            }
20        ),*
21        $(,)?
22    ) => {
23        #[derive(Clone, Debug, PartialEq, Serialize)]
24        #[serde(rename_all = "snake_case", tag = "action")]
25        pub enum ClickEvent {
26            $(
27                $action_variant {
28                    $(
29                        $(#[$meta])*
30                        $field: $type
31                    ),*
32                }
33            ),*
34        }
35
36        #[cfg(feature = "simdnbt")]
37        impl simdnbt::Serialize for ClickEvent {
38            fn to_compound(self) -> NbtCompound {
39                let mut compound = NbtCompound::new();
40                match self {
41                    $(
42                        Self::$action_variant { $($field),* } => {
43                            compound.insert("action", stringify!($action_name));
44                            $(
45                                compound.insert(stringify!($field), $field);
46                            )*
47                        }
48                    )*
49                };
50                compound
51            }
52        }
53
54        #[cfg(feature = "simdnbt")]
55        impl simdnbt::Deserialize for ClickEvent {
56            fn from_compound(
57                compound: simdnbt::borrow::NbtCompound,
58            ) -> Result<Self, simdnbt::DeserializeError> {
59                let action = get_in_compound::<String>(&compound, "action")?;
60                Ok(match action.as_str() {
61                    $(
62                        stringify!($action_name) => Self::$action_variant {
63                            $(
64                                $field: get_in_compound(&compound, stringify!($field))?
65                            ),*
66                        },
67                    )*
68                    _ => return Err(DeserializeError::MismatchedFieldType(action.to_owned())),
69                })
70            }
71        }
72
73    }
74}
75
76define_click_event_struct! {
77    open_url: OpenUrl {
78        url: String,
79    },
80    open_file: OpenFile {
81        path: String,
82    },
83    run_command: RunCommand {
84        command: String,
85    },
86    suggest_command: SuggestCommand {
87        command: String,
88    },
89    // TODO: this uses Dialog.CODEC
90    show_dialog: ShowDialog {},
91    change_page: ChangePage {
92        page: i32,
93    },
94    copy_to_clipboard: CopyToClipboard {
95        value: String,
96    },
97    custom: Custom {
98        id: String,
99        #[cfg(feature = "simdnbt")]
100        payload: Nbt,
101    },
102}