phoenixcord_sdk/
plugin.rs1use crate::types::{
8 Badge, ChatBarButton, ChatBarContext, Element, Event, MemberContext, MenuItem, MenuTarget,
9 Message, OutgoingEdit, OutgoingMessage, PluginInfo, PopoverButton, ProfileContext,
10 SendDecision, Style,
11};
12
13pub trait Plugin: Default + 'static {
20 fn info() -> PluginInfo;
22
23 fn start(&mut self) {}
24
25 fn stop(&mut self) {}
26
27 fn on_event(&mut self, _event: Event) {}
28
29 fn pre_send(&mut self, _message: OutgoingMessage) -> SendDecision {
30 SendDecision::Keep
31 }
32
33 fn pre_edit(&mut self, _edit: OutgoingEdit) -> SendDecision {
34 SendDecision::Keep
35 }
36
37 fn message_accessories(&mut self, _message: Message) -> Vec<Element> {
38 Vec::new()
39 }
40
41 fn message_decorations(&mut self, _message: Message) -> Vec<Element> {
42 Vec::new()
43 }
44
45 fn message_popover_buttons(&mut self, _message: Message) -> Vec<PopoverButton> {
46 Vec::new()
47 }
48
49 fn chat_bar_buttons(&mut self, _context: ChatBarContext) -> Vec<ChatBarButton> {
50 Vec::new()
51 }
52
53 fn context_menu(&mut self, _target: MenuTarget) -> Vec<MenuItem> {
54 Vec::new()
55 }
56
57 fn profile_sections(&mut self, _context: ProfileContext) -> Vec<Element> {
58 Vec::new()
59 }
60
61 fn user_badges(&mut self, _context: ProfileContext) -> Vec<Badge> {
62 Vec::new()
63 }
64
65 fn member_decorations(&mut self, _context: MemberContext) -> Vec<Element> {
66 Vec::new()
67 }
68
69 fn server_list_elements(&mut self) -> Vec<Element> {
70 Vec::new()
71 }
72
73 fn settings_panel(&mut self) -> Option<Element> {
74 None
75 }
76}
77
78impl PluginInfo {
79 pub fn new(name: &str, description: &str, authors: &[&str]) -> Self {
82 Self {
83 name: name.to_owned(),
84 description: description.to_owned(),
85 authors: authors.iter().map(|&author| author.to_owned()).collect(),
86 tags: Vec::new(),
87 dependencies: Vec::new(),
88 enabled_by_default: false,
89 required: false,
90 settings: Vec::new(),
91 commands: Vec::new(),
92 hooks: Vec::new(),
93 events: Vec::new(),
94 }
95 }
96}
97
98impl Default for Style {
99 fn default() -> Self {
100 Self {
101 direction: None,
102 align: None,
103 justify: None,
104 gap: None,
105 padding: None,
106 width: None,
107 height: None,
108 grow: false,
109 radius: None,
110 background: None,
111 foreground: None,
112 text_size: None,
113 text_weight: None,
114 }
115 }
116}
117
118#[macro_export]
121macro_rules! plugin {
122 ($plugin:ty) => {
123 struct PhoenixcordGuest;
124
125 ::std::thread_local! {
126 static PHOENIXCORD_INSTANCE: ::std::cell::RefCell<::std::option::Option<$plugin>> =
127 const { ::std::cell::RefCell::new(::std::option::Option::None) };
128 }
129
130 fn phoenixcord_with<R: ::std::default::Default>(f: impl FnOnce(&mut $plugin) -> R) -> R {
131 PHOENIXCORD_INSTANCE.with_borrow_mut(|instance| instance.as_mut().map(f).unwrap_or_default())
132 }
133
134 impl $crate::Guest for PhoenixcordGuest {
135 fn info() -> $crate::types::PluginInfo {
136 <$plugin as $crate::Plugin>::info()
137 }
138
139 fn start() {
140 PHOENIXCORD_INSTANCE.with_borrow_mut(|instance| {
141 $crate::Plugin::start(instance.insert(<$plugin>::default()))
142 });
143 }
144
145 fn stop() {
146 if let ::std::option::Option::Some(mut plugin) =
147 PHOENIXCORD_INSTANCE.with_borrow_mut(::std::option::Option::take)
148 {
149 $crate::Plugin::stop(&mut plugin);
150 }
151 }
152
153 fn on_event(event: $crate::types::Event) {
154 phoenixcord_with(|plugin| $crate::Plugin::on_event(plugin, event))
155 }
156
157 fn pre_send(message: $crate::types::OutgoingMessage) -> $crate::types::SendDecision {
158 PHOENIXCORD_INSTANCE.with_borrow_mut(|instance| match instance.as_mut() {
159 ::std::option::Option::Some(plugin) => $crate::Plugin::pre_send(plugin, message),
160 ::std::option::Option::None => $crate::types::SendDecision::Keep,
161 })
162 }
163
164 fn pre_edit(edit: $crate::types::OutgoingEdit) -> $crate::types::SendDecision {
165 PHOENIXCORD_INSTANCE.with_borrow_mut(|instance| match instance.as_mut() {
166 ::std::option::Option::Some(plugin) => $crate::Plugin::pre_edit(plugin, edit),
167 ::std::option::Option::None => $crate::types::SendDecision::Keep,
168 })
169 }
170
171 fn message_accessories(message: $crate::types::Message) -> ::std::vec::Vec<$crate::types::Element> {
172 phoenixcord_with(|plugin| $crate::Plugin::message_accessories(plugin, message))
173 }
174
175 fn message_decorations(message: $crate::types::Message) -> ::std::vec::Vec<$crate::types::Element> {
176 phoenixcord_with(|plugin| $crate::Plugin::message_decorations(plugin, message))
177 }
178
179 fn message_popover_buttons(message: $crate::types::Message) -> ::std::vec::Vec<$crate::types::PopoverButton> {
180 phoenixcord_with(|plugin| $crate::Plugin::message_popover_buttons(plugin, message))
181 }
182
183 fn chat_bar_buttons(context: $crate::types::ChatBarContext) -> ::std::vec::Vec<$crate::types::ChatBarButton> {
184 phoenixcord_with(|plugin| $crate::Plugin::chat_bar_buttons(plugin, context))
185 }
186
187 fn context_menu(target: $crate::types::MenuTarget) -> ::std::vec::Vec<$crate::types::MenuItem> {
188 phoenixcord_with(|plugin| $crate::Plugin::context_menu(plugin, target))
189 }
190
191 fn profile_sections(context: $crate::types::ProfileContext) -> ::std::vec::Vec<$crate::types::Element> {
192 phoenixcord_with(|plugin| $crate::Plugin::profile_sections(plugin, context))
193 }
194
195 fn user_badges(context: $crate::types::ProfileContext) -> ::std::vec::Vec<$crate::types::Badge> {
196 phoenixcord_with(|plugin| $crate::Plugin::user_badges(plugin, context))
197 }
198
199 fn member_decorations(context: $crate::types::MemberContext) -> ::std::vec::Vec<$crate::types::Element> {
200 phoenixcord_with(|plugin| $crate::Plugin::member_decorations(plugin, context))
201 }
202
203 fn server_list_elements() -> ::std::vec::Vec<$crate::types::Element> {
204 phoenixcord_with($crate::Plugin::server_list_elements)
205 }
206
207 fn settings_panel() -> ::std::option::Option<$crate::types::Element> {
208 phoenixcord_with($crate::Plugin::settings_panel)
209 }
210 }
211
212 $crate::export!(PhoenixcordGuest with_types_in $crate);
213 };
214}