1#[macro_export]
13macro_rules! println {
14 () => {
15 $crate::alloc::print("");
16 };
17 ($($arg:tt)*) => {
18 $crate::imports::std::print(&$crate::prelude::format!($($arg)*));
19 };
20}
21
22#[macro_export]
24macro_rules! debug {
25 () => {
26 #[cfg(debug_assertions)]
27 {
28 $crate::prelude::println!();
29 }
30 };
31 ($($arg:tt)*) => {
32 #[cfg(debug_assertions)]
33 {
34 $crate::prelude::println!($($arg)*);
35 }
36 };
37}
38
39#[macro_export]
44macro_rules! error {
45 ($($arg:tt)*) => {
46 $crate::AidokuError::message($crate::prelude::format!($($arg)*))
47 };
48}
49
50#[macro_export]
58macro_rules! bail {
59 ($($arg:tt)*) => {
60 return ::core::result::Result::Err($crate::error!($($arg)*));
61 };
62}
63
64#[macro_export]
81macro_rules! register_source {
82 ($source_type:ty $(, $param:ident)*) => {
83 static mut SOURCE: ::core::option::Option<$crate::alloc::Box<$source_type>> =
84 ::core::option::Option::None;
85
86 fn __source() -> &'static mut $source_type {
87 unsafe { SOURCE.as_deref_mut().unwrap() }
88 }
89
90 fn __handle_result<T: $crate::serde::Serialize>(
91 result: ::core::result::Result<T, $crate::imports::error::AidokuError>,
92 ) -> i32 {
93 match &result {
94 ::core::result::Result::Ok(result) => {
95 let mut bytes = $crate::postcard::to_allocvec(result).unwrap();
96
97 bytes.splice(0..0, [0,0,0,0,0,0,0,0]);
98 let len_bytes = (bytes.len() as i32).to_le_bytes();
99 bytes[0..4].copy_from_slice(&len_bytes);
100 let cap_bytes = (bytes.capacity() as i32).to_le_bytes();
101 bytes[4..8].copy_from_slice(&cap_bytes);
102
103 let ptr = bytes.as_ptr() as i32;
104 ::core::mem::forget(bytes);
105 ptr
106 }
107 ::core::result::Result::Err(err) => __handle_error(err),
108 }
109 }
110
111 fn __handle_error(error: &$crate::imports::error::AidokuError) -> i32 {
112 $crate::prelude::println!("Error: {:?}", error);
113 match error {
114 $crate::imports::error::AidokuError::Message(string) => {
115 let mut buffer = (-1 as i32).to_le_bytes().to_vec();
116
117 buffer.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
118 buffer.extend_from_slice(&string.as_bytes());
119
120 let cap_bytes = (buffer.capacity() as i32).to_le_bytes();
121 buffer[4..8].copy_from_slice(&cap_bytes);
122 let len_bytes = (buffer.len() as i32).to_le_bytes();
123 buffer[8..12].copy_from_slice(&len_bytes);
124
125 let ptr = buffer.as_ptr() as i32;
126 ::core::mem::forget(buffer);
127 ptr
128 }
129 error => error.error_code(),
130 }
131 }
132
133 #[unsafe(export_name = "start")]
135 pub extern "C" fn __start() {
136 unsafe {
137 SOURCE =
138 ::core::option::Option::Some($crate::alloc::Box::new(<$source_type>::new()))
139 };
140 }
141
142 #[unsafe(no_mangle)]
143 #[unsafe(export_name = "free_result")]
144 pub unsafe extern "C" fn __wasm_free_result(ptr: i32) {
145 $crate::imports::std::free_result(ptr);
146 }
147
148 #[unsafe(no_mangle)]
149 #[unsafe(export_name = "get_search_manga_list")]
150 pub unsafe extern "C" fn __wasm_get_search_manga_list(
151 query_descriptor: i32,
152 page: i32,
153 filters_descriptor: i32,
154 ) -> i32 {
155 let query = $crate::imports::std::read_string(query_descriptor);
156 let ::core::result::Result::Ok(filters) =
157 $crate::imports::std::read::<$crate::alloc::Vec<$crate::FilterValue>>(filters_descriptor)
158 else {
159 return -1;
160 };
161
162 let result = __source().get_search_manga_list(query, page, filters);
163 __handle_result(result)
164 }
165
166 #[unsafe(no_mangle)]
167 #[unsafe(export_name = "get_manga_update")]
168 pub unsafe extern "C" fn __wasm_get_manga_update(
169 manga_descriptor: i32,
170 needs_details: bool,
171 needs_chapters: bool,
172 ) -> i32 {
173 let ::core::result::Result::Ok(manga) =
174 $crate::imports::std::read::<$crate::Manga>(manga_descriptor)
175 else {
176 return -1;
177 };
178
179 let result = __source().get_manga_update(manga, needs_details, needs_chapters);
180 __handle_result(result)
181 }
182
183 #[unsafe(no_mangle)]
184 #[unsafe(export_name = "get_page_list")]
185 pub unsafe extern "C" fn __wasm_get_page_list(
186 manga_descriptor: i32,
187 chapter_descriptor: i32,
188 ) -> i32 {
189 let ::core::result::Result::Ok(manga) =
190 $crate::imports::std::read::<$crate::Manga>(manga_descriptor)
191 else {
192 return -1;
193 };
194 let ::core::result::Result::Ok(chapter) =
195 $crate::imports::std::read::<$crate::Chapter>(chapter_descriptor)
196 else {
197 return -2;
198 };
199
200 let result = __source()
201 .get_page_list(manga, chapter)
202 .map(|pages| {
203 pages.into_iter()
204 .map(|mut page| {
205 page.ensure_externally_managed();
206 page
207 })
208 .collect::<$crate::alloc::Vec<_>>()
209 });
210 __handle_result(result)
211 }
212
213 $(
214 register_source!(@single $param);
215 )*
216 };
217
218 (@single ListingProvider) => {
219 #[unsafe(no_mangle)]
220 #[unsafe(export_name = "get_manga_list")]
221 pub unsafe extern "C" fn __wasm_get_manga_list(listing_descriptor: i32, page: i32) -> i32 {
222 let ::core::result::Result::Ok(listing) =
223 $crate::imports::std::read::<$crate::Listing>(listing_descriptor)
224 else {
225 return -1;
226 };
227
228 use $crate::ListingProvider;
229 let result = __source().get_manga_list(listing, page);
230 __handle_result(result)
231 }
232 };
233
234 (@single Home) => {
235 #[unsafe(no_mangle)]
236 #[unsafe(export_name = "get_home")]
237 pub unsafe extern "C" fn __wasm_get_home() -> i32 {
238 use $crate::Home;
239 let result = __source().get_home();
240 __handle_result(result)
241 }
242 };
243
244 (@single DynamicListings) => {
245 #[unsafe(no_mangle)]
246 #[unsafe(export_name = "get_listings")]
247 pub unsafe extern "C" fn __wasm_get_listings() -> i32 {
248 use $crate::DynamicListings;
249 let result = __source().get_dynamic_listings();
250 __handle_result(result)
251 }
252 };
253
254 (@single DynamicFilters) => {
255 #[unsafe(no_mangle)]
256 #[unsafe(export_name = "get_filters")]
257 pub unsafe extern "C" fn __wasm_get_filters() -> i32 {
258 use $crate::DynamicFilters;
259 let result = __source().get_dynamic_filters();
260 __handle_result(result)
261 }
262 };
263
264 (@single DynamicSettings) => {
265 #[unsafe(no_mangle)]
266 #[unsafe(export_name = "get_settings")]
267 pub unsafe extern "C" fn __wasm_get_settings() -> i32 {
268 use $crate::DynamicSettings;
269 let result = __source().get_dynamic_settings();
270 __handle_result(result)
271 }
272 };
273
274 (@single PageImageProcessor) => {
275 #[unsafe(no_mangle)]
276 #[unsafe(export_name = "process_page_image")]
277 pub unsafe extern "C" fn __wasm_process_page_image(
278 response_descriptor: i32,
279 context_descriptor: i32,
280 ) -> i32 {
281 let ::core::result::Result::Ok(response) =
282 $crate::imports::std::read::<$crate::ImageResponse>(response_descriptor)
283 else {
284 return -1;
285 };
286 let context: ::core::option::Option<$crate::PageContext> = if context_descriptor < 0 {
287 None
288 } else if let ::core::result::Result::Ok(context) =
289 $crate::imports::std::read::<$crate::PageContext>(context_descriptor)
290 {
291 Some(context)
292 } else {
293 return -2;
294 };
295
296 use $crate::PageImageProcessor;
297 let mut result = __source().process_page_image(response, context);
298 if let Ok(image_ref) = result.as_mut() {
299 image_ref.externally_managed = true;
300 }
301 __handle_result(result.map(|r| r.rid))
302 }
303 };
304
305 (@single CoverImageProcessor) => {
306 #[unsafe(no_mangle)]
307 #[unsafe(export_name = "process_cover_image")]
308 pub unsafe extern "C" fn __wasm_process_cover_image(response_descriptor: i32) -> i32 {
309 let ::core::result::Result::Ok(response) =
310 $crate::imports::std::read::<$crate::ImageResponse>(response_descriptor)
311 else {
312 return -1;
313 };
314
315 use $crate::CoverImageProcessor;
316 let mut result = __source().process_cover_image(response);
317 if let Ok(image_ref) = result.as_mut() {
318 image_ref.externally_managed = true;
319 }
320 __handle_result(result.map(|r| r.rid))
321 }
322 };
323
324 (@single ImageRequestProvider) => {
325 #[unsafe(no_mangle)]
326 #[unsafe(export_name = "get_image_request")]
327 pub unsafe extern "C" fn __wasm_get_image_request(
328 url_descriptor: i32,
329 context_descriptor: i32,
330 ) -> i32 {
331 let ::core::result::Result::Ok(url) =
332 $crate::imports::std::read::<$crate::alloc::String>(url_descriptor)
333 else {
334 return -1;
335 };
336 let context: ::core::option::Option<$crate::PageContext> = if context_descriptor < 0 {
337 None
338 } else if let ::core::result::Result::Ok(context) =
339 $crate::imports::std::read::<$crate::PageContext>(context_descriptor)
340 {
341 Some(context)
342 } else {
343 return -2;
344 };
345
346 use $crate::ImageRequestProvider;
347 let mut result = __source().get_image_request(url, context);
348 if let Ok(request) = result.as_mut() {
349 request.should_close = false;
350 }
351 __handle_result(result.map(|r| r.rid))
352 }
353 };
354
355 (@single PageDescriptionProvider) => {
356 #[unsafe(no_mangle)]
357 #[unsafe(export_name = "get_page_description")]
358 pub unsafe extern "C" fn __wasm_get_page_description(page_descriptor: i32) -> i32 {
359 let ::core::result::Result::Ok(page) =
360 $crate::imports::std::read::<$crate::Page>(page_descriptor)
361 else {
362 return -1;
363 };
364 use $crate::PageDescriptionProvider;
365 let result = __source().get_page_description(page);
366 __handle_result(result)
367 }
368 };
369
370 (@single AlternateCoverProvider) => {
371 #[unsafe(no_mangle)]
372 #[unsafe(export_name = "get_alternate_covers")]
373 pub unsafe extern "C" fn __wasm_get_alternate_covers(manga_descriptor: i32) -> i32 {
374 let ::core::result::Result::Ok(manga) =
375 $crate::imports::std::read::<$crate::Manga>(manga_descriptor)
376 else {
377 return -1;
378 };
379 use $crate::AlternateCoverProvider;
380 let result = __source().get_alternate_covers(manga);
381 __handle_result(result)
382 }
383 };
384
385 (@single BaseUrlProvider) => {
386 #[unsafe(no_mangle)]
387 #[unsafe(export_name = "get_base_url")]
388 pub unsafe extern "C" fn __wasm_get_base_url() -> i32 {
389 use $crate::BaseUrlProvider;
390 let result = __source().get_base_url();
391 __handle_result(result)
392 }
393 };
394
395 (@single NotificationHandler) => {
396 #[unsafe(no_mangle)]
397 #[unsafe(export_name = "handle_notification")]
398 pub unsafe extern "C" fn __wasm_handle_notification(string_descriptor: i32) -> i32 {
399 let ::core::result::Result::Ok(notification) =
400 $crate::imports::std::read::<$crate::alloc::String>(string_descriptor)
401 else {
402 return -1;
403 };
404 use $crate::NotificationHandler;
405 __source().handle_notification(notification);
406 return 0;
407 }
408 };
409
410 (@single DeepLinkHandler) => {
411 #[unsafe(no_mangle)]
412 #[unsafe(export_name = "handle_deep_link")]
413 pub unsafe extern "C" fn __wasm_handle_deep_link(string_descriptor: i32) -> i32 {
414 let ::core::result::Result::Ok(url) =
415 $crate::imports::std::read::<$crate::alloc::String>(string_descriptor)
416 else {
417 return -1;
418 };
419 use $crate::DeepLinkHandler;
420 let result = __source().handle_deep_link(url);
421 __handle_result(result)
422 }
423 };
424
425 (@single BasicLoginHandler) => {
426 #[unsafe(no_mangle)]
427 #[unsafe(export_name = "handle_basic_login")]
428 pub unsafe extern "C" fn __wasm_handle_basic_login(
429 key_descriptor: i32,
430 username_descriptor: i32,
431 password_descriptor: i32,
432 ) -> i32 {
433 let ::core::result::Result::Ok(key) =
434 $crate::imports::std::read::<$crate::alloc::String>(key_descriptor)
435 else {
436 return -1;
437 };
438 let ::core::result::Result::Ok(username) =
439 $crate::imports::std::read::<$crate::alloc::String>(username_descriptor)
440 else {
441 return -2;
442 };
443 let ::core::result::Result::Ok(password) =
444 $crate::imports::std::read::<$crate::alloc::String>(password_descriptor)
445 else {
446 return -3;
447 };
448 use $crate::BasicLoginHandler;
449 let result = __source().handle_basic_login(key, username, password);
450 __handle_result(result)
451 }
452 };
453
454 (@single WebLoginHandler) => {
455 #[unsafe(no_mangle)]
456 #[unsafe(export_name = "handle_web_login")]
457 pub unsafe extern "C" fn __wasm_handle_web_login(
458 key_descriptor: i32,
459 keys_descriptor: i32,
460 values_descriptor: i32,
461 ) -> i32 {
462 let ::core::result::Result::Ok(key) =
463 $crate::imports::std::read::<$crate::alloc::String>(key_descriptor)
464 else {
465 return -1;
466 };
467 let ::core::result::Result::Ok(keys) = $crate::imports::std::read::<
468 $crate::alloc::Vec<$crate::alloc::String>,
469 >(keys_descriptor) else {
470 return -2;
471 };
472 let ::core::result::Result::Ok(values) = $crate::imports::std::read::<
473 $crate::alloc::Vec<$crate::alloc::String>,
474 >(values_descriptor) else {
475 return -3;
476 };
477 use $crate::WebLoginHandler;
478 let result = __source().handle_web_login(key, keys.into_iter().zip(values).collect());
479 __handle_result(result)
480 }
481 };
482
483 (@single MigrationHandler) => {
484 #[unsafe(no_mangle)]
485 #[unsafe(export_name = "handle_key_migration")]
486 pub unsafe extern "C" fn __wasm_handle_key_migration(
487 key_kind: i32,
488 manga_key_descriptor: i32,
489 chapter_key_descriptor: i32,
490 ) -> i32 {
491 let ::core::result::Result::Ok(manga_key) =
492 $crate::imports::std::read::<$crate::alloc::String>(manga_key_descriptor)
493 else {
494 return -1;
495 };
496 use $crate::MigrationHandler;
497 let result = match key_kind {
498 0 => __source().handle_manga_migration(manga_key),
500 1 => {
502 let ::core::result::Result::Ok(chapter_key) =
503 $crate::imports::std::read::<$crate::alloc::String>(chapter_key_descriptor)
504 else {
505 return -2;
506 };
507 __source().handle_chapter_migration(manga_key, chapter_key)
508 }
509 _ => return -3,
510 };
511 __handle_result(result)
512 }
513 };
514}