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