ayaka_bindings_types/plugin.rs
1use crate::*;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5/// The bit flags to describe plugin type.
6///
7/// Every plugin should provide a function `plugin_type`,
8/// which returns [`PluginType`].
9///
10/// ```ignore
11/// use ayaka_bindings::*;
12///
13/// #[export]
14/// fn plugin_type() -> PluginType {
15/// PluginType::default()
16/// }
17/// ```
18#[derive(Debug, Default, Clone, Serialize, Deserialize)]
19pub struct PluginType {
20 /// The action plugin.
21 /// This plugin processes the action after they are parsed.
22 pub action: bool,
23 /// The text plugin.
24 /// The custom text commands are dealt with this type of plugin.
25 pub text: Vec<String>,
26 /// The line plugin.
27 /// The custom line types are dealt with this type of plugin.
28 pub line: Vec<String>,
29 /// The game plugin.
30 /// This plugin processes the game properties after it is loaded.
31 pub game: bool,
32}
33
34impl PluginType {
35 /// Creates a [`PluginTypeBuilder`] instance to build a [`PluginType`].
36 pub fn builder() -> PluginTypeBuilder {
37 PluginTypeBuilder {
38 data: Self::default(),
39 }
40 }
41}
42
43/// The builder of [`PluginType`].
44pub struct PluginTypeBuilder {
45 data: PluginType,
46}
47
48impl PluginTypeBuilder {
49 /// An action plugin.
50 pub fn action(mut self) -> Self {
51 self.data.action = true;
52 self
53 }
54
55 /// A text plugin, which provides commands.
56 pub fn text(mut self, cmds: impl IntoIterator<Item = impl Into<String>>) -> Self {
57 self.data.text = cmds.into_iter().map(|s| s.into()).collect();
58 self
59 }
60
61 /// A line plugins, which provides custom line types.
62 pub fn line(mut self, cmds: impl IntoIterator<Item = impl Into<String>>) -> Self {
63 self.data.line = cmds.into_iter().map(|s| s.into()).collect();
64 self
65 }
66
67 /// A game plugin.
68 pub fn game(mut self) -> Self {
69 self.data.game = true;
70 self
71 }
72
73 /// Build a [`PluginType`].
74 pub fn build(self) -> PluginType {
75 self.data
76 }
77}
78
79/// The type of current frontend.
80#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
81pub enum FrontendType {
82 /// The frontend only accepts raw texts.
83 Text,
84 /// The frontend renders HTML.
85 Html,
86 /// The frontend renders LaTeX.
87 Latex,
88}
89
90/// The argument to action plugin.
91///
92/// Every action plugin should implement `process_action`:
93/// ```ignore
94/// use ayaka_bindings::*;
95///
96/// #[export]
97/// fn process_action(mut ctx: ActionProcessContext) -> ActionProcessResult {
98/// // Process the action...
99/// ActionProcessResult { action: ctx.action }
100/// }
101/// ```
102#[derive(Debug, Serialize, Deserialize)]
103pub struct ActionProcessContext {
104 /// The global properties of the game profile.
105 pub game_props: HashMap<String, String>,
106 /// The frontend type.
107 pub frontend: FrontendType,
108 /// The current context.
109 pub ctx: RawContext,
110 /// The current action.
111 pub action: ActionText,
112}
113
114#[derive(Debug, Serialize)]
115#[doc(hidden)]
116pub struct ActionProcessContextRef<'a> {
117 pub game_props: &'a HashMap<String, String>,
118 pub frontend: FrontendType,
119 pub ctx: &'a RawContext,
120 pub action: &'a ActionText,
121}
122
123/// The result of action plugins.
124/// See examples at [`ActionProcessContext`].
125#[derive(Debug, Default, Serialize, Deserialize)]
126pub struct ActionProcessResult {
127 /// The processed action text.
128 pub action: ActionText,
129}
130
131/// The argument to text plugin.
132///
133/// ```ignore
134/// use ayaka_bindings::*;
135///
136/// #[export]
137/// fn plugin_type() -> PluginType {
138/// PluginType::builder().text(&["hello"]).build()
139/// }
140///
141/// #[export]
142/// fn hello(_args: Vec<String>, _ctx: TextProcessContext) -> TextProcessResult {
143/// let mut res = TextProcessResult::default();
144/// res.line.push_back_chars("hello");
145/// res
146/// }
147/// ```
148#[derive(Debug, Serialize, Deserialize)]
149pub struct TextProcessContext {
150 /// The global properties of the game profile.
151 pub game_props: HashMap<String, String>,
152 /// The frontend type.
153 pub frontend: FrontendType,
154}
155
156#[derive(Debug, Serialize)]
157#[doc(hidden)]
158pub struct TextProcessContextRef<'a> {
159 pub game_props: &'a HashMap<String, String>,
160 pub frontend: FrontendType,
161}
162
163/// The result of commands in text plugins.
164/// See examples at [`TextProcessContext`].
165#[derive(Debug, Default, Serialize, Deserialize)]
166pub struct TextProcessResult {
167 /// The lines to append.
168 pub text: ActionText,
169}
170
171/// The argument to game plugin.
172///
173/// Every game plugin should implement `process_game`:
174/// ```ignore
175/// use ayaka_bindings::*;
176///
177/// #[export]
178/// fn process_game(mut ctx: GameProcessContext) -> GameProcessResult {
179/// // Process the game...
180/// GameProcessResult { props: ctx.props }
181/// }
182/// ```
183#[derive(Debug, Serialize, Deserialize)]
184pub struct GameProcessContext {
185 /// The title of the game.
186 pub title: String,
187 /// The author of the game.
188 pub author: String,
189 /// The global properties of the game.
190 pub props: HashMap<String, String>,
191}
192
193#[derive(Debug, Serialize)]
194#[doc(hidden)]
195pub struct GameProcessContextRef<'a> {
196 pub title: &'a str,
197 pub author: &'a str,
198 pub props: &'a HashMap<String, String>,
199}
200
201/// The result of game plugins.
202/// See examples at [`GameProcessContext`].
203#[derive(Debug, Serialize, Deserialize)]
204pub struct GameProcessResult {
205 /// The updated properties.
206 pub props: HashMap<String, String>,
207}
208
209/// The argument to line plugin.
210///
211/// ```ignore
212/// use ayaka_bindings::*;
213///
214/// #[export]
215/// fn plugin_type() -> PluginType {
216/// PluginType::builder().line(&["hello"]).build()
217/// }
218///
219/// #[export]
220/// fn hello(_ctx: LineProcessContext) -> LineProcessResult {
221/// let mut res = LineProcessResult::default();
222/// res.locals.insert("hello".to_string(), RawValue::Str("world".to_string()));
223/// res
224/// }
225/// ```
226#[derive(Debug, Serialize, Deserialize)]
227pub struct LineProcessContext {
228 /// The global properties of the game profile.
229 pub game_props: HashMap<String, String>,
230 /// The frontend type.
231 pub frontend: FrontendType,
232 /// The current context.
233 pub ctx: RawContext,
234 /// The full properties of the custom command.
235 pub props: VarMap,
236}
237
238#[derive(Debug, Serialize)]
239#[doc(hidden)]
240pub struct LineProcessContextRef<'a> {
241 pub game_props: &'a HashMap<String, String>,
242 pub frontend: FrontendType,
243 pub ctx: &'a RawContext,
244 pub props: &'a VarMap,
245}
246
247/// The result of commands in line plugins.
248/// See examples at [`LineProcessContext`].
249#[derive(Debug, Default, Serialize, Deserialize)]
250pub struct LineProcessResult {
251 /// The updated variables.
252 pub locals: VarMap,
253 /// The temp variables.
254 pub vars: VarMap,
255}