crawlberg 1.5.0 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  // This file is auto-generated by alef. DO NOT EDIT.
2
- // alef:hash:45a77cf71e37c29533a0d31a68c73f8d55de1a5aebed5f50b90fd1d2d0790b2f
2
+ // alef:hash:202c4f469a62d77930ef13ac10e1718ac319e02c448ba94573bae7ab48c1d4ce
3
3
  // Re-generate with: alef generate
4
4
  #![allow(dead_code, unused_imports, unused_variables)]
5
5
  #![allow(
@@ -24,6 +24,52 @@ use magnus::{Error, IntoValueFromNative, Ruby, function, method, prelude::*, try
24
24
  use std::collections::HashMap;
25
25
  use std::sync::Arc;
26
26
 
27
+ /// Run owned Rust work while the calling Ruby thread releases the GVL.
28
+ fn alef_magnus_run_without_gvl<F, T>(callback: F) -> T
29
+ where
30
+ F: FnOnce() -> T,
31
+ {
32
+ struct RunState<F, T> {
33
+ callback: Option<F>,
34
+ result: Option<std::thread::Result<T>>,
35
+ }
36
+
37
+ extern "C" fn run_without_gvl<F, T>(data: *mut std::ffi::c_void) -> *mut std::ffi::c_void
38
+ where
39
+ F: FnOnce() -> T,
40
+ {
41
+ // SAFETY: `data` points to the caller's RunState for the duration of this callback.
42
+ let state = unsafe { &mut *(data as *mut RunState<F, T>) };
43
+ let Some(callback) = state.callback.take() else {
44
+ state.result = Some(Err(Box::new("Alef Magnus callback already consumed")));
45
+ return std::ptr::null_mut();
46
+ };
47
+ state.result = Some(std::panic::catch_unwind(std::panic::AssertUnwindSafe(callback)));
48
+ std::ptr::null_mut()
49
+ }
50
+
51
+ extern "C" fn unblock_run(_data: *mut std::ffi::c_void) {}
52
+
53
+ let mut state = RunState {
54
+ callback: Some(callback),
55
+ result: None,
56
+ };
57
+ // SAFETY: Ruby invokes the callback synchronously, and `state` remains live until it returns.
58
+ unsafe {
59
+ rb_sys::rb_thread_call_without_gvl(
60
+ Some(run_without_gvl::<F, T>),
61
+ &mut state as *mut RunState<F, T> as *mut std::ffi::c_void,
62
+ Some(unblock_run),
63
+ std::ptr::null_mut(),
64
+ );
65
+ }
66
+
67
+ match state.result.expect("Alef Magnus callback did not run") {
68
+ Ok(result) => result,
69
+ Err(payload) => std::panic::resume_unwind(payload),
70
+ }
71
+ }
72
+
27
73
  fn json_to_ruby(handle: &Ruby, val: serde_json::Value) -> magnus::Value {
28
74
  use magnus::IntoValue;
29
75
  match val {
@@ -114,24 +160,51 @@ impl ActionResult {
114
160
  let (kwargs_opt,) = args.optional;
115
161
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
116
162
  Ok(Self {
117
- action_index: kwargs
118
- .get(ruby.to_symbol("action_index"))
119
- .and_then(|v| usize::try_convert(v).ok())
120
- .unwrap_or_default(),
121
- action_type: kwargs
122
- .get(ruby.to_symbol("action_type"))
123
- .and_then(|v| String::try_convert(v).ok())
124
- .unwrap_or_default(),
125
- success: kwargs
126
- .get(ruby.to_symbol("success"))
127
- .and_then(|v| bool::try_convert(v).ok())
128
- .unwrap_or_default(),
129
- data: kwargs
130
- .get(ruby.to_symbol("data"))
131
- .and_then(|v| String::try_convert(v).ok()),
132
- error: kwargs
133
- .get(ruby.to_symbol("error"))
134
- .and_then(|v| String::try_convert(v).ok()),
163
+ action_index: match kwargs.get(ruby.to_symbol("action_index")) {
164
+ Some(v) => usize::try_convert(v).map_err(|e| {
165
+ magnus::Error::new(
166
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
167
+ format!("invalid value for `action_index`: {}", e),
168
+ )
169
+ })?,
170
+ None => Default::default(),
171
+ },
172
+ action_type: match kwargs.get(ruby.to_symbol("action_type")) {
173
+ Some(v) => String::try_convert(v).map_err(|e| {
174
+ magnus::Error::new(
175
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
176
+ format!("invalid value for `action_type`: {}", e),
177
+ )
178
+ })?,
179
+ None => Default::default(),
180
+ },
181
+ success: match kwargs.get(ruby.to_symbol("success")) {
182
+ Some(v) => bool::try_convert(v).map_err(|e| {
183
+ magnus::Error::new(
184
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
185
+ format!("invalid value for `success`: {}", e),
186
+ )
187
+ })?,
188
+ None => Default::default(),
189
+ },
190
+ data: match kwargs.get(ruby.to_symbol("data")).filter(|v| !v.is_nil()) {
191
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
192
+ magnus::Error::new(
193
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
194
+ format!("invalid value for `data`: {}", e),
195
+ )
196
+ })?),
197
+ None => None,
198
+ },
199
+ error: match kwargs.get(ruby.to_symbol("error")).filter(|v| !v.is_nil()) {
200
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
201
+ magnus::Error::new(
202
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
203
+ format!("invalid value for `error`: {}", e),
204
+ )
205
+ })?),
206
+ None => None,
207
+ },
135
208
  })
136
209
  }
137
210
 
@@ -208,22 +281,51 @@ impl ArticleMetadata {
208
281
  let (kwargs_opt,) = args.optional;
209
282
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
210
283
  Ok(Self {
211
- published_time: kwargs
212
- .get(ruby.to_symbol("published_time"))
213
- .and_then(|v| String::try_convert(v).ok()),
214
- modified_time: kwargs
215
- .get(ruby.to_symbol("modified_time"))
216
- .and_then(|v| String::try_convert(v).ok()),
217
- author: kwargs
218
- .get(ruby.to_symbol("author"))
219
- .and_then(|v| String::try_convert(v).ok()),
220
- section: kwargs
221
- .get(ruby.to_symbol("section"))
222
- .and_then(|v| String::try_convert(v).ok()),
223
- tags: kwargs
224
- .get(ruby.to_symbol("tags"))
225
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
226
- .unwrap_or_default(),
284
+ published_time: match kwargs.get(ruby.to_symbol("published_time")).filter(|v| !v.is_nil()) {
285
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
286
+ magnus::Error::new(
287
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
288
+ format!("invalid value for `published_time`: {}", e),
289
+ )
290
+ })?),
291
+ None => None,
292
+ },
293
+ modified_time: match kwargs.get(ruby.to_symbol("modified_time")).filter(|v| !v.is_nil()) {
294
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
295
+ magnus::Error::new(
296
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
297
+ format!("invalid value for `modified_time`: {}", e),
298
+ )
299
+ })?),
300
+ None => None,
301
+ },
302
+ author: match kwargs.get(ruby.to_symbol("author")).filter(|v| !v.is_nil()) {
303
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
304
+ magnus::Error::new(
305
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
306
+ format!("invalid value for `author`: {}", e),
307
+ )
308
+ })?),
309
+ None => None,
310
+ },
311
+ section: match kwargs.get(ruby.to_symbol("section")).filter(|v| !v.is_nil()) {
312
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
313
+ magnus::Error::new(
314
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
315
+ format!("invalid value for `section`: {}", e),
316
+ )
317
+ })?),
318
+ None => None,
319
+ },
320
+ tags: match kwargs.get(ruby.to_symbol("tags")) {
321
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
322
+ magnus::Error::new(
323
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
324
+ format!("invalid value for `tags`: {}", e),
325
+ )
326
+ })?,
327
+ None => Default::default(),
328
+ },
227
329
  })
228
330
  }
229
331
 
@@ -298,16 +400,33 @@ impl BatchCrawlResult {
298
400
  let (kwargs_opt,) = args.optional;
299
401
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
300
402
  Ok(Self {
301
- url: kwargs
302
- .get(ruby.to_symbol("url"))
303
- .and_then(|v| String::try_convert(v).ok())
304
- .unwrap_or_default(),
305
- result: kwargs
306
- .get(ruby.to_symbol("result"))
307
- .and_then(|v| CrawlResult::try_convert(v).ok()),
308
- error: kwargs
309
- .get(ruby.to_symbol("error"))
310
- .and_then(|v| String::try_convert(v).ok()),
403
+ url: match kwargs.get(ruby.to_symbol("url")) {
404
+ Some(v) => String::try_convert(v).map_err(|e| {
405
+ magnus::Error::new(
406
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
407
+ format!("invalid value for `url`: {}", e),
408
+ )
409
+ })?,
410
+ None => Default::default(),
411
+ },
412
+ result: match kwargs.get(ruby.to_symbol("result")).filter(|v| !v.is_nil()) {
413
+ Some(v) => Some(CrawlResult::try_convert(v).map_err(|e| {
414
+ magnus::Error::new(
415
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
416
+ format!("invalid value for `result`: {}", e),
417
+ )
418
+ })?),
419
+ None => None,
420
+ },
421
+ error: match kwargs.get(ruby.to_symbol("error")).filter(|v| !v.is_nil()) {
422
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
423
+ magnus::Error::new(
424
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
425
+ format!("invalid value for `error`: {}", e),
426
+ )
427
+ })?),
428
+ None => None,
429
+ },
311
430
  })
312
431
  }
313
432
 
@@ -375,22 +494,42 @@ impl BatchCrawlResults {
375
494
  let (kwargs_opt,) = args.optional;
376
495
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
377
496
  Ok(Self {
378
- results: kwargs
379
- .get(ruby.to_symbol("results"))
380
- .and_then(|v| <Vec<BatchCrawlResult>>::try_convert(v).ok())
381
- .unwrap_or_default(),
382
- total_count: kwargs
383
- .get(ruby.to_symbol("total_count"))
384
- .and_then(|v| usize::try_convert(v).ok())
385
- .unwrap_or_default(),
386
- completed_count: kwargs
387
- .get(ruby.to_symbol("completed_count"))
388
- .and_then(|v| usize::try_convert(v).ok())
389
- .unwrap_or_default(),
390
- failed_count: kwargs
391
- .get(ruby.to_symbol("failed_count"))
392
- .and_then(|v| usize::try_convert(v).ok())
393
- .unwrap_or_default(),
497
+ results: match kwargs.get(ruby.to_symbol("results")) {
498
+ Some(v) => <Vec<BatchCrawlResult>>::try_convert(v).map_err(|e| {
499
+ magnus::Error::new(
500
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
501
+ format!("invalid value for `results`: {}", e),
502
+ )
503
+ })?,
504
+ None => Default::default(),
505
+ },
506
+ total_count: match kwargs.get(ruby.to_symbol("total_count")) {
507
+ Some(v) => usize::try_convert(v).map_err(|e| {
508
+ magnus::Error::new(
509
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
510
+ format!("invalid value for `total_count`: {}", e),
511
+ )
512
+ })?,
513
+ None => Default::default(),
514
+ },
515
+ completed_count: match kwargs.get(ruby.to_symbol("completed_count")) {
516
+ Some(v) => usize::try_convert(v).map_err(|e| {
517
+ magnus::Error::new(
518
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
519
+ format!("invalid value for `completed_count`: {}", e),
520
+ )
521
+ })?,
522
+ None => Default::default(),
523
+ },
524
+ failed_count: match kwargs.get(ruby.to_symbol("failed_count")) {
525
+ Some(v) => usize::try_convert(v).map_err(|e| {
526
+ magnus::Error::new(
527
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
528
+ format!("invalid value for `failed_count`: {}", e),
529
+ )
530
+ })?,
531
+ None => Default::default(),
532
+ },
394
533
  })
395
534
  }
396
535
 
@@ -419,8 +558,10 @@ pub struct BatchCrawlStreamRequest {
419
558
  urls: Vec<String>,
420
559
  }
421
560
 
561
+ #[cfg(not(target_arch = "wasm32"))]
422
562
  unsafe impl IntoValueFromNative for BatchCrawlStreamRequest {}
423
563
 
564
+ #[cfg(not(target_arch = "wasm32"))]
424
565
  impl magnus::TryConvert for BatchCrawlStreamRequest {
425
566
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
426
567
  if let Ok(r) = <&BatchCrawlStreamRequest as magnus::TryConvert>::try_convert(val) {
@@ -445,6 +586,7 @@ impl magnus::TryConvert for BatchCrawlStreamRequest {
445
586
  }
446
587
  }
447
588
 
589
+ #[cfg(not(target_arch = "wasm32"))]
448
590
  unsafe impl TryConvertOwned for BatchCrawlStreamRequest {}
449
591
 
450
592
  #[cfg(not(target_arch = "wasm32"))]
@@ -462,10 +604,15 @@ impl BatchCrawlStreamRequest {
462
604
  let (kwargs_opt,) = args.optional;
463
605
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
464
606
  Ok(Self {
465
- urls: kwargs
466
- .get(ruby.to_symbol("urls"))
467
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
468
- .unwrap_or_default(),
607
+ urls: match kwargs.get(ruby.to_symbol("urls")) {
608
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
609
+ magnus::Error::new(
610
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
611
+ format!("invalid value for `urls`: {}", e),
612
+ )
613
+ })?,
614
+ None => Default::default(),
615
+ },
469
616
  })
470
617
  }
471
618
 
@@ -524,16 +671,33 @@ impl BatchScrapeResult {
524
671
  let (kwargs_opt,) = args.optional;
525
672
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
526
673
  Ok(Self {
527
- url: kwargs
528
- .get(ruby.to_symbol("url"))
529
- .and_then(|v| String::try_convert(v).ok())
530
- .unwrap_or_default(),
531
- result: kwargs
532
- .get(ruby.to_symbol("result"))
533
- .and_then(|v| ScrapeResult::try_convert(v).ok()),
534
- error: kwargs
535
- .get(ruby.to_symbol("error"))
536
- .and_then(|v| String::try_convert(v).ok()),
674
+ url: match kwargs.get(ruby.to_symbol("url")) {
675
+ Some(v) => String::try_convert(v).map_err(|e| {
676
+ magnus::Error::new(
677
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
678
+ format!("invalid value for `url`: {}", e),
679
+ )
680
+ })?,
681
+ None => Default::default(),
682
+ },
683
+ result: match kwargs.get(ruby.to_symbol("result")).filter(|v| !v.is_nil()) {
684
+ Some(v) => Some(ScrapeResult::try_convert(v).map_err(|e| {
685
+ magnus::Error::new(
686
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
687
+ format!("invalid value for `result`: {}", e),
688
+ )
689
+ })?),
690
+ None => None,
691
+ },
692
+ error: match kwargs.get(ruby.to_symbol("error")).filter(|v| !v.is_nil()) {
693
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
694
+ magnus::Error::new(
695
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
696
+ format!("invalid value for `error`: {}", e),
697
+ )
698
+ })?),
699
+ None => None,
700
+ },
537
701
  })
538
702
  }
539
703
 
@@ -601,22 +765,42 @@ impl BatchScrapeResults {
601
765
  let (kwargs_opt,) = args.optional;
602
766
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
603
767
  Ok(Self {
604
- results: kwargs
605
- .get(ruby.to_symbol("results"))
606
- .and_then(|v| <Vec<BatchScrapeResult>>::try_convert(v).ok())
607
- .unwrap_or_default(),
608
- total_count: kwargs
609
- .get(ruby.to_symbol("total_count"))
610
- .and_then(|v| usize::try_convert(v).ok())
611
- .unwrap_or_default(),
612
- completed_count: kwargs
613
- .get(ruby.to_symbol("completed_count"))
614
- .and_then(|v| usize::try_convert(v).ok())
615
- .unwrap_or_default(),
616
- failed_count: kwargs
617
- .get(ruby.to_symbol("failed_count"))
618
- .and_then(|v| usize::try_convert(v).ok())
619
- .unwrap_or_default(),
768
+ results: match kwargs.get(ruby.to_symbol("results")) {
769
+ Some(v) => <Vec<BatchScrapeResult>>::try_convert(v).map_err(|e| {
770
+ magnus::Error::new(
771
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
772
+ format!("invalid value for `results`: {}", e),
773
+ )
774
+ })?,
775
+ None => Default::default(),
776
+ },
777
+ total_count: match kwargs.get(ruby.to_symbol("total_count")) {
778
+ Some(v) => usize::try_convert(v).map_err(|e| {
779
+ magnus::Error::new(
780
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
781
+ format!("invalid value for `total_count`: {}", e),
782
+ )
783
+ })?,
784
+ None => Default::default(),
785
+ },
786
+ completed_count: match kwargs.get(ruby.to_symbol("completed_count")) {
787
+ Some(v) => usize::try_convert(v).map_err(|e| {
788
+ magnus::Error::new(
789
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
790
+ format!("invalid value for `completed_count`: {}", e),
791
+ )
792
+ })?,
793
+ None => Default::default(),
794
+ },
795
+ failed_count: match kwargs.get(ruby.to_symbol("failed_count")) {
796
+ Some(v) => usize::try_convert(v).map_err(|e| {
797
+ magnus::Error::new(
798
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
799
+ format!("invalid value for `failed_count`: {}", e),
800
+ )
801
+ })?,
802
+ None => Default::default(),
803
+ },
620
804
  })
621
805
  }
622
806
 
@@ -706,52 +890,123 @@ impl BrowserConfig {
706
890
  let (kwargs_opt,) = args.optional;
707
891
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
708
892
  Ok(Self {
709
- mode: kwargs
710
- .get(ruby.to_symbol("mode"))
711
- .and_then(|v| BrowserMode::try_convert(v).ok())
712
- .unwrap_or(BrowserMode::Auto),
713
- backend: kwargs
714
- .get(ruby.to_symbol("backend"))
715
- .and_then(|v| BrowserBackend::try_convert(v).ok())
716
- .unwrap_or(BrowserBackend::Chromiumoxide),
717
- endpoint: kwargs
718
- .get(ruby.to_symbol("endpoint"))
719
- .and_then(|v| String::try_convert(v).ok()),
720
- timeout: kwargs
721
- .get(ruby.to_symbol("timeout"))
722
- .and_then(|v| u64::try_convert(v).ok())
723
- .unwrap_or(30000),
724
- wait: kwargs
725
- .get(ruby.to_symbol("wait"))
726
- .and_then(|v| BrowserWait::try_convert(v).ok())
727
- .unwrap_or(BrowserWait::NetworkIdle),
728
- wait_selector: kwargs
729
- .get(ruby.to_symbol("wait_selector"))
730
- .and_then(|v| String::try_convert(v).ok()),
731
- extra_wait: kwargs
732
- .get(ruby.to_symbol("extra_wait"))
733
- .and_then(|v| u64::try_convert(v).ok()),
734
- proxy: kwargs
735
- .get(ruby.to_symbol("proxy"))
736
- .and_then(|v| ProxyConfig::try_convert(v).ok()),
737
- block_url_patterns: kwargs
738
- .get(ruby.to_symbol("block_url_patterns"))
739
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
740
- .unwrap_or_default(),
741
- eval_script: kwargs
742
- .get(ruby.to_symbol("eval_script"))
743
- .and_then(|v| String::try_convert(v).ok()),
744
- robots_user_agent: kwargs
745
- .get(ruby.to_symbol("robots_user_agent"))
746
- .and_then(|v| String::try_convert(v).ok()),
747
- capture_network_events: kwargs
748
- .get(ruby.to_symbol("capture_network_events"))
749
- .and_then(|v| bool::try_convert(v).ok())
750
- .unwrap_or(false),
751
- session_affinity: kwargs
752
- .get(ruby.to_symbol("session_affinity"))
753
- .and_then(|v| bool::try_convert(v).ok())
754
- .unwrap_or(true),
893
+ mode: match kwargs.get(ruby.to_symbol("mode")) {
894
+ Some(v) => BrowserMode::try_convert(v).map_err(|e| {
895
+ magnus::Error::new(
896
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
897
+ format!("invalid value for `mode`: {}", e),
898
+ )
899
+ })?,
900
+ None => BrowserMode::Auto,
901
+ },
902
+ backend: match kwargs.get(ruby.to_symbol("backend")) {
903
+ Some(v) => BrowserBackend::try_convert(v).map_err(|e| {
904
+ magnus::Error::new(
905
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
906
+ format!("invalid value for `backend`: {}", e),
907
+ )
908
+ })?,
909
+ None => BrowserBackend::Chromiumoxide,
910
+ },
911
+ endpoint: match kwargs.get(ruby.to_symbol("endpoint")).filter(|v| !v.is_nil()) {
912
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
913
+ magnus::Error::new(
914
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
915
+ format!("invalid value for `endpoint`: {}", e),
916
+ )
917
+ })?),
918
+ None => None,
919
+ },
920
+ timeout: match kwargs.get(ruby.to_symbol("timeout")) {
921
+ Some(v) => u64::try_convert(v).map_err(|e| {
922
+ magnus::Error::new(
923
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
924
+ format!("invalid value for `timeout`: {}", e),
925
+ )
926
+ })?,
927
+ None => 30000,
928
+ },
929
+ wait: match kwargs.get(ruby.to_symbol("wait")) {
930
+ Some(v) => BrowserWait::try_convert(v).map_err(|e| {
931
+ magnus::Error::new(
932
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
933
+ format!("invalid value for `wait`: {}", e),
934
+ )
935
+ })?,
936
+ None => BrowserWait::NetworkIdle,
937
+ },
938
+ wait_selector: match kwargs.get(ruby.to_symbol("wait_selector")).filter(|v| !v.is_nil()) {
939
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
940
+ magnus::Error::new(
941
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
942
+ format!("invalid value for `wait_selector`: {}", e),
943
+ )
944
+ })?),
945
+ None => None,
946
+ },
947
+ extra_wait: match kwargs.get(ruby.to_symbol("extra_wait")).filter(|v| !v.is_nil()) {
948
+ Some(v) => Some(u64::try_convert(v).map_err(|e| {
949
+ magnus::Error::new(
950
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
951
+ format!("invalid value for `extra_wait`: {}", e),
952
+ )
953
+ })?),
954
+ None => None,
955
+ },
956
+ proxy: match kwargs.get(ruby.to_symbol("proxy")).filter(|v| !v.is_nil()) {
957
+ Some(v) => Some(ProxyConfig::try_convert(v).map_err(|e| {
958
+ magnus::Error::new(
959
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
960
+ format!("invalid value for `proxy`: {}", e),
961
+ )
962
+ })?),
963
+ None => None,
964
+ },
965
+ block_url_patterns: match kwargs.get(ruby.to_symbol("block_url_patterns")) {
966
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
967
+ magnus::Error::new(
968
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
969
+ format!("invalid value for `block_url_patterns`: {}", e),
970
+ )
971
+ })?,
972
+ None => Default::default(),
973
+ },
974
+ eval_script: match kwargs.get(ruby.to_symbol("eval_script")).filter(|v| !v.is_nil()) {
975
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
976
+ magnus::Error::new(
977
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
978
+ format!("invalid value for `eval_script`: {}", e),
979
+ )
980
+ })?),
981
+ None => None,
982
+ },
983
+ robots_user_agent: match kwargs.get(ruby.to_symbol("robots_user_agent")).filter(|v| !v.is_nil()) {
984
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
985
+ magnus::Error::new(
986
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
987
+ format!("invalid value for `robots_user_agent`: {}", e),
988
+ )
989
+ })?),
990
+ None => None,
991
+ },
992
+ capture_network_events: match kwargs.get(ruby.to_symbol("capture_network_events")) {
993
+ Some(v) => bool::try_convert(v).map_err(|e| {
994
+ magnus::Error::new(
995
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
996
+ format!("invalid value for `capture_network_events`: {}", e),
997
+ )
998
+ })?,
999
+ None => false,
1000
+ },
1001
+ session_affinity: match kwargs.get(ruby.to_symbol("session_affinity")) {
1002
+ Some(v) => bool::try_convert(v).map_err(|e| {
1003
+ magnus::Error::new(
1004
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1005
+ format!("invalid value for `session_affinity`: {}", e),
1006
+ )
1007
+ })?,
1008
+ None => true,
1009
+ },
755
1010
  })
756
1011
  }
757
1012
 
@@ -866,17 +1121,33 @@ impl BrowserExtras {
866
1121
  let (kwargs_opt,) = args.optional;
867
1122
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
868
1123
  Ok(Self {
869
- eval_result: kwargs
870
- .get(ruby.to_symbol("eval_result"))
871
- .and_then(|v| String::try_convert(v).ok()),
872
- network_events: kwargs
873
- .get(ruby.to_symbol("network_events"))
874
- .and_then(|v| <Vec<ResponseMeta>>::try_convert(v).ok())
875
- .unwrap_or_default(),
876
- cookies: kwargs
877
- .get(ruby.to_symbol("cookies"))
878
- .and_then(|v| <Vec<CookieInfo>>::try_convert(v).ok())
879
- .unwrap_or_default(),
1124
+ eval_result: match kwargs.get(ruby.to_symbol("eval_result")).filter(|v| !v.is_nil()) {
1125
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
1126
+ magnus::Error::new(
1127
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1128
+ format!("invalid value for `eval_result`: {}", e),
1129
+ )
1130
+ })?),
1131
+ None => None,
1132
+ },
1133
+ network_events: match kwargs.get(ruby.to_symbol("network_events")) {
1134
+ Some(v) => <Vec<ResponseMeta>>::try_convert(v).map_err(|e| {
1135
+ magnus::Error::new(
1136
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1137
+ format!("invalid value for `network_events`: {}", e),
1138
+ )
1139
+ })?,
1140
+ None => Default::default(),
1141
+ },
1142
+ cookies: match kwargs.get(ruby.to_symbol("cookies")) {
1143
+ Some(v) => <Vec<CookieInfo>>::try_convert(v).map_err(|e| {
1144
+ magnus::Error::new(
1145
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1146
+ format!("invalid value for `cookies`: {}", e),
1147
+ )
1148
+ })?,
1149
+ None => Default::default(),
1150
+ },
880
1151
  })
881
1152
  }
882
1153
 
@@ -943,18 +1214,33 @@ impl CitationReference {
943
1214
  let (kwargs_opt,) = args.optional;
944
1215
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
945
1216
  Ok(Self {
946
- index: kwargs
947
- .get(ruby.to_symbol("index"))
948
- .and_then(|v| usize::try_convert(v).ok())
949
- .unwrap_or_default(),
950
- url: kwargs
951
- .get(ruby.to_symbol("url"))
952
- .and_then(|v| String::try_convert(v).ok())
953
- .unwrap_or_default(),
954
- text: kwargs
955
- .get(ruby.to_symbol("text"))
956
- .and_then(|v| String::try_convert(v).ok())
957
- .unwrap_or_default(),
1217
+ index: match kwargs.get(ruby.to_symbol("index")) {
1218
+ Some(v) => usize::try_convert(v).map_err(|e| {
1219
+ magnus::Error::new(
1220
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1221
+ format!("invalid value for `index`: {}", e),
1222
+ )
1223
+ })?,
1224
+ None => Default::default(),
1225
+ },
1226
+ url: match kwargs.get(ruby.to_symbol("url")) {
1227
+ Some(v) => String::try_convert(v).map_err(|e| {
1228
+ magnus::Error::new(
1229
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1230
+ format!("invalid value for `url`: {}", e),
1231
+ )
1232
+ })?,
1233
+ None => Default::default(),
1234
+ },
1235
+ text: match kwargs.get(ruby.to_symbol("text")) {
1236
+ Some(v) => String::try_convert(v).map_err(|e| {
1237
+ magnus::Error::new(
1238
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1239
+ format!("invalid value for `text`: {}", e),
1240
+ )
1241
+ })?,
1242
+ None => Default::default(),
1243
+ },
958
1244
  })
959
1245
  }
960
1246
 
@@ -1020,14 +1306,24 @@ impl CitationResult {
1020
1306
  let (kwargs_opt,) = args.optional;
1021
1307
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
1022
1308
  Ok(Self {
1023
- content: kwargs
1024
- .get(ruby.to_symbol("content"))
1025
- .and_then(|v| String::try_convert(v).ok())
1026
- .unwrap_or_default(),
1027
- references: kwargs
1028
- .get(ruby.to_symbol("references"))
1029
- .and_then(|v| <Vec<CitationReference>>::try_convert(v).ok())
1030
- .unwrap_or_default(),
1309
+ content: match kwargs.get(ruby.to_symbol("content")) {
1310
+ Some(v) => String::try_convert(v).map_err(|e| {
1311
+ magnus::Error::new(
1312
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1313
+ format!("invalid value for `content`: {}", e),
1314
+ )
1315
+ })?,
1316
+ None => Default::default(),
1317
+ },
1318
+ references: match kwargs.get(ruby.to_symbol("references")) {
1319
+ Some(v) => <Vec<CitationReference>>::try_convert(v).map_err(|e| {
1320
+ magnus::Error::new(
1321
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1322
+ format!("invalid value for `references`: {}", e),
1323
+ )
1324
+ })?,
1325
+ None => Default::default(),
1326
+ },
1031
1327
  })
1032
1328
  }
1033
1329
 
@@ -1112,53 +1408,114 @@ impl ContentConfig {
1112
1408
  let (kwargs_opt,) = args.optional;
1113
1409
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
1114
1410
  Ok(Self {
1115
- output_format: kwargs
1116
- .get(ruby.to_symbol("output_format"))
1117
- .and_then(|v| String::try_convert(v).ok())
1118
- .unwrap_or("markdown".to_string()),
1119
- preprocessing_preset: kwargs
1120
- .get(ruby.to_symbol("preprocessing_preset"))
1121
- .and_then(|v| String::try_convert(v).ok())
1122
- .unwrap_or("standard".to_string()),
1123
- remove_navigation: kwargs
1124
- .get(ruby.to_symbol("remove_navigation"))
1125
- .and_then(|v| bool::try_convert(v).ok())
1126
- .unwrap_or(true),
1127
- remove_forms: kwargs
1128
- .get(ruby.to_symbol("remove_forms"))
1129
- .and_then(|v| bool::try_convert(v).ok())
1130
- .unwrap_or(true),
1131
- strip_tags: kwargs
1132
- .get(ruby.to_symbol("strip_tags"))
1133
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
1134
- .unwrap_or_default(),
1135
- preserve_tags: kwargs
1136
- .get(ruby.to_symbol("preserve_tags"))
1137
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
1138
- .unwrap_or_default(),
1139
- exclude_selectors: kwargs
1140
- .get(ruby.to_symbol("exclude_selectors"))
1141
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
1142
- .unwrap_or(vec!["noscript".to_string()]),
1143
- skip_images: kwargs
1144
- .get(ruby.to_symbol("skip_images"))
1145
- .and_then(|v| bool::try_convert(v).ok())
1146
- .unwrap_or(false),
1147
- max_depth: kwargs
1148
- .get(ruby.to_symbol("max_depth"))
1149
- .and_then(|v| usize::try_convert(v).ok()),
1150
- wrap: kwargs
1151
- .get(ruby.to_symbol("wrap"))
1152
- .and_then(|v| bool::try_convert(v).ok())
1153
- .unwrap_or(false),
1154
- wrap_width: kwargs
1155
- .get(ruby.to_symbol("wrap_width"))
1156
- .and_then(|v| usize::try_convert(v).ok())
1157
- .unwrap_or(80),
1158
- include_document_structure: kwargs
1159
- .get(ruby.to_symbol("include_document_structure"))
1160
- .and_then(|v| bool::try_convert(v).ok())
1161
- .unwrap_or(true),
1411
+ output_format: match kwargs.get(ruby.to_symbol("output_format")) {
1412
+ Some(v) => String::try_convert(v).map_err(|e| {
1413
+ magnus::Error::new(
1414
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1415
+ format!("invalid value for `output_format`: {}", e),
1416
+ )
1417
+ })?,
1418
+ None => "markdown".to_string(),
1419
+ },
1420
+ preprocessing_preset: match kwargs.get(ruby.to_symbol("preprocessing_preset")) {
1421
+ Some(v) => String::try_convert(v).map_err(|e| {
1422
+ magnus::Error::new(
1423
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1424
+ format!("invalid value for `preprocessing_preset`: {}", e),
1425
+ )
1426
+ })?,
1427
+ None => "standard".to_string(),
1428
+ },
1429
+ remove_navigation: match kwargs.get(ruby.to_symbol("remove_navigation")) {
1430
+ Some(v) => bool::try_convert(v).map_err(|e| {
1431
+ magnus::Error::new(
1432
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1433
+ format!("invalid value for `remove_navigation`: {}", e),
1434
+ )
1435
+ })?,
1436
+ None => true,
1437
+ },
1438
+ remove_forms: match kwargs.get(ruby.to_symbol("remove_forms")) {
1439
+ Some(v) => bool::try_convert(v).map_err(|e| {
1440
+ magnus::Error::new(
1441
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1442
+ format!("invalid value for `remove_forms`: {}", e),
1443
+ )
1444
+ })?,
1445
+ None => true,
1446
+ },
1447
+ strip_tags: match kwargs.get(ruby.to_symbol("strip_tags")) {
1448
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
1449
+ magnus::Error::new(
1450
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1451
+ format!("invalid value for `strip_tags`: {}", e),
1452
+ )
1453
+ })?,
1454
+ None => Default::default(),
1455
+ },
1456
+ preserve_tags: match kwargs.get(ruby.to_symbol("preserve_tags")) {
1457
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
1458
+ magnus::Error::new(
1459
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1460
+ format!("invalid value for `preserve_tags`: {}", e),
1461
+ )
1462
+ })?,
1463
+ None => Default::default(),
1464
+ },
1465
+ exclude_selectors: match kwargs.get(ruby.to_symbol("exclude_selectors")) {
1466
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
1467
+ magnus::Error::new(
1468
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1469
+ format!("invalid value for `exclude_selectors`: {}", e),
1470
+ )
1471
+ })?,
1472
+ None => vec!["noscript".to_string()],
1473
+ },
1474
+ skip_images: match kwargs.get(ruby.to_symbol("skip_images")) {
1475
+ Some(v) => bool::try_convert(v).map_err(|e| {
1476
+ magnus::Error::new(
1477
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1478
+ format!("invalid value for `skip_images`: {}", e),
1479
+ )
1480
+ })?,
1481
+ None => false,
1482
+ },
1483
+ max_depth: match kwargs.get(ruby.to_symbol("max_depth")).filter(|v| !v.is_nil()) {
1484
+ Some(v) => Some(usize::try_convert(v).map_err(|e| {
1485
+ magnus::Error::new(
1486
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1487
+ format!("invalid value for `max_depth`: {}", e),
1488
+ )
1489
+ })?),
1490
+ None => None,
1491
+ },
1492
+ wrap: match kwargs.get(ruby.to_symbol("wrap")) {
1493
+ Some(v) => bool::try_convert(v).map_err(|e| {
1494
+ magnus::Error::new(
1495
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1496
+ format!("invalid value for `wrap`: {}", e),
1497
+ )
1498
+ })?,
1499
+ None => false,
1500
+ },
1501
+ wrap_width: match kwargs.get(ruby.to_symbol("wrap_width")) {
1502
+ Some(v) => usize::try_convert(v).map_err(|e| {
1503
+ magnus::Error::new(
1504
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1505
+ format!("invalid value for `wrap_width`: {}", e),
1506
+ )
1507
+ })?,
1508
+ None => 80,
1509
+ },
1510
+ include_document_structure: match kwargs.get(ruby.to_symbol("include_document_structure")) {
1511
+ Some(v) => bool::try_convert(v).map_err(|e| {
1512
+ magnus::Error::new(
1513
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1514
+ format!("invalid value for `include_document_structure`: {}", e),
1515
+ )
1516
+ })?,
1517
+ None => true,
1518
+ },
1162
1519
  })
1163
1520
  }
1164
1521
 
@@ -1262,20 +1619,42 @@ impl CookieInfo {
1262
1619
  let (kwargs_opt,) = args.optional;
1263
1620
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
1264
1621
  Ok(Self {
1265
- name: kwargs
1266
- .get(ruby.to_symbol("name"))
1267
- .and_then(|v| String::try_convert(v).ok())
1268
- .unwrap_or_default(),
1269
- value: kwargs
1270
- .get(ruby.to_symbol("value"))
1271
- .and_then(|v| String::try_convert(v).ok())
1272
- .unwrap_or_default(),
1273
- domain: kwargs
1274
- .get(ruby.to_symbol("domain"))
1275
- .and_then(|v| String::try_convert(v).ok()),
1276
- path: kwargs
1277
- .get(ruby.to_symbol("path"))
1278
- .and_then(|v| String::try_convert(v).ok()),
1622
+ name: match kwargs.get(ruby.to_symbol("name")) {
1623
+ Some(v) => String::try_convert(v).map_err(|e| {
1624
+ magnus::Error::new(
1625
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1626
+ format!("invalid value for `name`: {}", e),
1627
+ )
1628
+ })?,
1629
+ None => Default::default(),
1630
+ },
1631
+ value: match kwargs.get(ruby.to_symbol("value")) {
1632
+ Some(v) => String::try_convert(v).map_err(|e| {
1633
+ magnus::Error::new(
1634
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1635
+ format!("invalid value for `value`: {}", e),
1636
+ )
1637
+ })?,
1638
+ None => Default::default(),
1639
+ },
1640
+ domain: match kwargs.get(ruby.to_symbol("domain")).filter(|v| !v.is_nil()) {
1641
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
1642
+ magnus::Error::new(
1643
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1644
+ format!("invalid value for `domain`: {}", e),
1645
+ )
1646
+ })?),
1647
+ None => None,
1648
+ },
1649
+ path: match kwargs.get(ruby.to_symbol("path")).filter(|v| !v.is_nil()) {
1650
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
1651
+ magnus::Error::new(
1652
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1653
+ format!("invalid value for `path`: {}", e),
1654
+ )
1655
+ })?),
1656
+ None => None,
1657
+ },
1279
1658
  })
1280
1659
  }
1281
1660
 
@@ -1391,172 +1770,438 @@ impl CrawlConfig {
1391
1770
  let (kwargs_opt,) = args.optional;
1392
1771
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
1393
1772
  Ok(Self {
1394
- max_depth: kwargs
1395
- .get(ruby.to_symbol("max_depth"))
1396
- .and_then(|v| usize::try_convert(v).ok()),
1397
- max_pages: kwargs
1398
- .get(ruby.to_symbol("max_pages"))
1399
- .and_then(|v| usize::try_convert(v).ok()),
1400
- max_links_per_page: kwargs
1401
- .get(ruby.to_symbol("max_links_per_page"))
1402
- .and_then(|v| usize::try_convert(v).ok()),
1403
- max_concurrent: kwargs
1404
- .get(ruby.to_symbol("max_concurrent"))
1405
- .and_then(|v| usize::try_convert(v).ok()),
1406
- crawl_strategy: kwargs
1407
- .get(ruby.to_symbol("crawl_strategy"))
1408
- .and_then(|v| CrawlStrategyKind::try_convert(v).ok())
1409
- .unwrap_or(CrawlStrategyKind::Bfs),
1410
- content_filter: kwargs
1411
- .get(ruby.to_symbol("content_filter"))
1412
- .and_then(|v| ContentFilterKind::try_convert(v).ok()),
1413
- bm25_query: kwargs
1414
- .get(ruby.to_symbol("bm25_query"))
1415
- .and_then(|v| String::try_convert(v).ok()),
1416
- bm25_threshold: kwargs
1417
- .get(ruby.to_symbol("bm25_threshold"))
1418
- .and_then(|v| f64::try_convert(v).ok()),
1419
- respect_robots_txt: kwargs
1420
- .get(ruby.to_symbol("respect_robots_txt"))
1421
- .and_then(|v| bool::try_convert(v).ok())
1422
- .unwrap_or(false),
1423
- soft_http_errors: kwargs
1424
- .get(ruby.to_symbol("soft_http_errors"))
1425
- .and_then(|v| bool::try_convert(v).ok())
1426
- .unwrap_or(false),
1427
- user_agent: kwargs
1428
- .get(ruby.to_symbol("user_agent"))
1429
- .and_then(|v| String::try_convert(v).ok()),
1430
- stay_on_domain: kwargs
1431
- .get(ruby.to_symbol("stay_on_domain"))
1432
- .and_then(|v| bool::try_convert(v).ok())
1433
- .unwrap_or(false),
1434
- allow_subdomains: kwargs
1435
- .get(ruby.to_symbol("allow_subdomains"))
1436
- .and_then(|v| bool::try_convert(v).ok())
1437
- .unwrap_or(false),
1438
- include_paths: kwargs
1439
- .get(ruby.to_symbol("include_paths"))
1440
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
1441
- .unwrap_or_default(),
1442
- exclude_paths: kwargs
1443
- .get(ruby.to_symbol("exclude_paths"))
1444
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
1445
- .unwrap_or_default(),
1446
- custom_headers: kwargs
1447
- .get(ruby.to_symbol("custom_headers"))
1448
- .and_then(|v| <HashMap<String, String>>::try_convert(v).ok())
1449
- .unwrap_or_default(),
1450
- request_timeout: kwargs
1451
- .get(ruby.to_symbol("request_timeout"))
1452
- .and_then(|v| u64::try_convert(v).ok())
1453
- .unwrap_or(30000),
1454
- rate_limit_ms: kwargs
1455
- .get(ruby.to_symbol("rate_limit_ms"))
1456
- .and_then(|v| u64::try_convert(v).ok()),
1457
- max_redirects: kwargs
1458
- .get(ruby.to_symbol("max_redirects"))
1459
- .and_then(|v| usize::try_convert(v).ok())
1460
- .unwrap_or(10),
1461
- retry_count: kwargs
1462
- .get(ruby.to_symbol("retry_count"))
1463
- .and_then(|v| usize::try_convert(v).ok())
1464
- .unwrap_or(0),
1465
- retry_codes: kwargs
1466
- .get(ruby.to_symbol("retry_codes"))
1467
- .and_then(|v| <Vec<u16>>::try_convert(v).ok())
1468
- .unwrap_or_default(),
1469
- cookies_enabled: kwargs
1470
- .get(ruby.to_symbol("cookies_enabled"))
1471
- .and_then(|v| bool::try_convert(v).ok())
1472
- .unwrap_or(false),
1473
- auth: kwargs
1474
- .get(ruby.to_symbol("auth"))
1475
- .and_then(|v| AuthConfig::try_convert(v).ok()),
1476
- max_body_size: kwargs
1477
- .get(ruby.to_symbol("max_body_size"))
1478
- .and_then(|v| usize::try_convert(v).ok()),
1479
- remove_tags: kwargs
1480
- .get(ruby.to_symbol("remove_tags"))
1481
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
1482
- .unwrap_or_default(),
1483
- content: kwargs
1484
- .get(ruby.to_symbol("content"))
1485
- .and_then(|v| ContentConfig::try_convert(v).ok())
1486
- .unwrap_or_default(),
1487
- map_limit: kwargs
1488
- .get(ruby.to_symbol("map_limit"))
1489
- .and_then(|v| usize::try_convert(v).ok()),
1490
- map_search: kwargs
1491
- .get(ruby.to_symbol("map_search"))
1492
- .and_then(|v| String::try_convert(v).ok()),
1493
- download_assets: kwargs
1494
- .get(ruby.to_symbol("download_assets"))
1495
- .and_then(|v| bool::try_convert(v).ok())
1496
- .unwrap_or(false),
1497
- asset_types: kwargs
1498
- .get(ruby.to_symbol("asset_types"))
1499
- .and_then(|v| <Vec<AssetCategory>>::try_convert(v).ok())
1500
- .unwrap_or_default(),
1501
- max_asset_size: kwargs
1502
- .get(ruby.to_symbol("max_asset_size"))
1503
- .and_then(|v| usize::try_convert(v).ok()),
1504
- browser: kwargs
1505
- .get(ruby.to_symbol("browser"))
1506
- .and_then(|v| BrowserConfig::try_convert(v).ok())
1507
- .unwrap_or_default(),
1508
- proxy: kwargs
1509
- .get(ruby.to_symbol("proxy"))
1510
- .and_then(|v| ProxyConfig::try_convert(v).ok()),
1511
- user_agents: kwargs
1512
- .get(ruby.to_symbol("user_agents"))
1513
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
1514
- .unwrap_or_default(),
1515
- capture_screenshot: kwargs
1516
- .get(ruby.to_symbol("capture_screenshot"))
1517
- .and_then(|v| bool::try_convert(v).ok())
1518
- .unwrap_or(false),
1519
- follow_document_urls: kwargs
1520
- .get(ruby.to_symbol("follow_document_urls"))
1521
- .and_then(|v| bool::try_convert(v).ok())
1522
- .unwrap_or(false),
1523
- document_url_depth: kwargs
1524
- .get(ruby.to_symbol("document_url_depth"))
1525
- .and_then(|v| u32::try_convert(v).ok()),
1526
- download_documents: kwargs
1527
- .get(ruby.to_symbol("download_documents"))
1528
- .and_then(|v| bool::try_convert(v).ok())
1529
- .unwrap_or(true),
1530
- document_max_size: kwargs
1531
- .get(ruby.to_symbol("document_max_size"))
1532
- .and_then(|v| usize::try_convert(v).ok()),
1533
- document_mime_types: kwargs
1534
- .get(ruby.to_symbol("document_mime_types"))
1535
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
1536
- .unwrap_or_default(),
1537
- document_output_dir: kwargs
1773
+ max_depth: match kwargs.get(ruby.to_symbol("max_depth")).filter(|v| !v.is_nil()) {
1774
+ Some(v) => Some(usize::try_convert(v).map_err(|e| {
1775
+ magnus::Error::new(
1776
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1777
+ format!("invalid value for `max_depth`: {}", e),
1778
+ )
1779
+ })?),
1780
+ None => None,
1781
+ },
1782
+ max_pages: match kwargs.get(ruby.to_symbol("max_pages")).filter(|v| !v.is_nil()) {
1783
+ Some(v) => Some(usize::try_convert(v).map_err(|e| {
1784
+ magnus::Error::new(
1785
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1786
+ format!("invalid value for `max_pages`: {}", e),
1787
+ )
1788
+ })?),
1789
+ None => None,
1790
+ },
1791
+ max_links_per_page: match kwargs.get(ruby.to_symbol("max_links_per_page")).filter(|v| !v.is_nil()) {
1792
+ Some(v) => Some(usize::try_convert(v).map_err(|e| {
1793
+ magnus::Error::new(
1794
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1795
+ format!("invalid value for `max_links_per_page`: {}", e),
1796
+ )
1797
+ })?),
1798
+ None => None,
1799
+ },
1800
+ max_concurrent: match kwargs.get(ruby.to_symbol("max_concurrent")).filter(|v| !v.is_nil()) {
1801
+ Some(v) => Some(usize::try_convert(v).map_err(|e| {
1802
+ magnus::Error::new(
1803
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1804
+ format!("invalid value for `max_concurrent`: {}", e),
1805
+ )
1806
+ })?),
1807
+ None => None,
1808
+ },
1809
+ crawl_strategy: match kwargs.get(ruby.to_symbol("crawl_strategy")) {
1810
+ Some(v) => CrawlStrategyKind::try_convert(v).map_err(|e| {
1811
+ magnus::Error::new(
1812
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1813
+ format!("invalid value for `crawl_strategy`: {}", e),
1814
+ )
1815
+ })?,
1816
+ None => CrawlStrategyKind::Bfs,
1817
+ },
1818
+ content_filter: match kwargs.get(ruby.to_symbol("content_filter")).filter(|v| !v.is_nil()) {
1819
+ Some(v) => Some(ContentFilterKind::try_convert(v).map_err(|e| {
1820
+ magnus::Error::new(
1821
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1822
+ format!("invalid value for `content_filter`: {}", e),
1823
+ )
1824
+ })?),
1825
+ None => None,
1826
+ },
1827
+ bm25_query: match kwargs.get(ruby.to_symbol("bm25_query")).filter(|v| !v.is_nil()) {
1828
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
1829
+ magnus::Error::new(
1830
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1831
+ format!("invalid value for `bm25_query`: {}", e),
1832
+ )
1833
+ })?),
1834
+ None => None,
1835
+ },
1836
+ bm25_threshold: match kwargs.get(ruby.to_symbol("bm25_threshold")).filter(|v| !v.is_nil()) {
1837
+ Some(v) => Some(f64::try_convert(v).map_err(|e| {
1838
+ magnus::Error::new(
1839
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1840
+ format!("invalid value for `bm25_threshold`: {}", e),
1841
+ )
1842
+ })?),
1843
+ None => None,
1844
+ },
1845
+ respect_robots_txt: match kwargs.get(ruby.to_symbol("respect_robots_txt")) {
1846
+ Some(v) => bool::try_convert(v).map_err(|e| {
1847
+ magnus::Error::new(
1848
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1849
+ format!("invalid value for `respect_robots_txt`: {}", e),
1850
+ )
1851
+ })?,
1852
+ None => false,
1853
+ },
1854
+ soft_http_errors: match kwargs.get(ruby.to_symbol("soft_http_errors")) {
1855
+ Some(v) => bool::try_convert(v).map_err(|e| {
1856
+ magnus::Error::new(
1857
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1858
+ format!("invalid value for `soft_http_errors`: {}", e),
1859
+ )
1860
+ })?,
1861
+ None => false,
1862
+ },
1863
+ user_agent: match kwargs.get(ruby.to_symbol("user_agent")).filter(|v| !v.is_nil()) {
1864
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
1865
+ magnus::Error::new(
1866
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1867
+ format!("invalid value for `user_agent`: {}", e),
1868
+ )
1869
+ })?),
1870
+ None => None,
1871
+ },
1872
+ stay_on_domain: match kwargs.get(ruby.to_symbol("stay_on_domain")) {
1873
+ Some(v) => bool::try_convert(v).map_err(|e| {
1874
+ magnus::Error::new(
1875
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1876
+ format!("invalid value for `stay_on_domain`: {}", e),
1877
+ )
1878
+ })?,
1879
+ None => false,
1880
+ },
1881
+ allow_subdomains: match kwargs.get(ruby.to_symbol("allow_subdomains")) {
1882
+ Some(v) => bool::try_convert(v).map_err(|e| {
1883
+ magnus::Error::new(
1884
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1885
+ format!("invalid value for `allow_subdomains`: {}", e),
1886
+ )
1887
+ })?,
1888
+ None => false,
1889
+ },
1890
+ include_paths: match kwargs.get(ruby.to_symbol("include_paths")) {
1891
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
1892
+ magnus::Error::new(
1893
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1894
+ format!("invalid value for `include_paths`: {}", e),
1895
+ )
1896
+ })?,
1897
+ None => Default::default(),
1898
+ },
1899
+ exclude_paths: match kwargs.get(ruby.to_symbol("exclude_paths")) {
1900
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
1901
+ magnus::Error::new(
1902
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1903
+ format!("invalid value for `exclude_paths`: {}", e),
1904
+ )
1905
+ })?,
1906
+ None => Default::default(),
1907
+ },
1908
+ custom_headers: match kwargs.get(ruby.to_symbol("custom_headers")) {
1909
+ Some(v) => <HashMap<String, String>>::try_convert(v).map_err(|e| {
1910
+ magnus::Error::new(
1911
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1912
+ format!("invalid value for `custom_headers`: {}", e),
1913
+ )
1914
+ })?,
1915
+ None => Default::default(),
1916
+ },
1917
+ request_timeout: match kwargs.get(ruby.to_symbol("request_timeout")) {
1918
+ Some(v) => u64::try_convert(v).map_err(|e| {
1919
+ magnus::Error::new(
1920
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1921
+ format!("invalid value for `request_timeout`: {}", e),
1922
+ )
1923
+ })?,
1924
+ None => 30000,
1925
+ },
1926
+ rate_limit_ms: match kwargs.get(ruby.to_symbol("rate_limit_ms")).filter(|v| !v.is_nil()) {
1927
+ Some(v) => Some(u64::try_convert(v).map_err(|e| {
1928
+ magnus::Error::new(
1929
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1930
+ format!("invalid value for `rate_limit_ms`: {}", e),
1931
+ )
1932
+ })?),
1933
+ None => None,
1934
+ },
1935
+ max_redirects: match kwargs.get(ruby.to_symbol("max_redirects")) {
1936
+ Some(v) => usize::try_convert(v).map_err(|e| {
1937
+ magnus::Error::new(
1938
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1939
+ format!("invalid value for `max_redirects`: {}", e),
1940
+ )
1941
+ })?,
1942
+ None => 10,
1943
+ },
1944
+ retry_count: match kwargs.get(ruby.to_symbol("retry_count")) {
1945
+ Some(v) => usize::try_convert(v).map_err(|e| {
1946
+ magnus::Error::new(
1947
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1948
+ format!("invalid value for `retry_count`: {}", e),
1949
+ )
1950
+ })?,
1951
+ None => 0,
1952
+ },
1953
+ retry_codes: match kwargs.get(ruby.to_symbol("retry_codes")) {
1954
+ Some(v) => <Vec<u16>>::try_convert(v).map_err(|e| {
1955
+ magnus::Error::new(
1956
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1957
+ format!("invalid value for `retry_codes`: {}", e),
1958
+ )
1959
+ })?,
1960
+ None => Default::default(),
1961
+ },
1962
+ cookies_enabled: match kwargs.get(ruby.to_symbol("cookies_enabled")) {
1963
+ Some(v) => bool::try_convert(v).map_err(|e| {
1964
+ magnus::Error::new(
1965
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1966
+ format!("invalid value for `cookies_enabled`: {}", e),
1967
+ )
1968
+ })?,
1969
+ None => false,
1970
+ },
1971
+ auth: match kwargs.get(ruby.to_symbol("auth")).filter(|v| !v.is_nil()) {
1972
+ Some(v) => Some(AuthConfig::try_convert(v).map_err(|e| {
1973
+ magnus::Error::new(
1974
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1975
+ format!("invalid value for `auth`: {}", e),
1976
+ )
1977
+ })?),
1978
+ None => None,
1979
+ },
1980
+ max_body_size: match kwargs.get(ruby.to_symbol("max_body_size")).filter(|v| !v.is_nil()) {
1981
+ Some(v) => Some(usize::try_convert(v).map_err(|e| {
1982
+ magnus::Error::new(
1983
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1984
+ format!("invalid value for `max_body_size`: {}", e),
1985
+ )
1986
+ })?),
1987
+ None => None,
1988
+ },
1989
+ remove_tags: match kwargs.get(ruby.to_symbol("remove_tags")) {
1990
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
1991
+ magnus::Error::new(
1992
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1993
+ format!("invalid value for `remove_tags`: {}", e),
1994
+ )
1995
+ })?,
1996
+ None => Default::default(),
1997
+ },
1998
+ content: match kwargs.get(ruby.to_symbol("content")) {
1999
+ Some(v) => ContentConfig::try_convert(v).map_err(|e| {
2000
+ magnus::Error::new(
2001
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2002
+ format!("invalid value for `content`: {}", e),
2003
+ )
2004
+ })?,
2005
+ None => Default::default(),
2006
+ },
2007
+ map_limit: match kwargs.get(ruby.to_symbol("map_limit")).filter(|v| !v.is_nil()) {
2008
+ Some(v) => Some(usize::try_convert(v).map_err(|e| {
2009
+ magnus::Error::new(
2010
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2011
+ format!("invalid value for `map_limit`: {}", e),
2012
+ )
2013
+ })?),
2014
+ None => None,
2015
+ },
2016
+ map_search: match kwargs.get(ruby.to_symbol("map_search")).filter(|v| !v.is_nil()) {
2017
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
2018
+ magnus::Error::new(
2019
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2020
+ format!("invalid value for `map_search`: {}", e),
2021
+ )
2022
+ })?),
2023
+ None => None,
2024
+ },
2025
+ download_assets: match kwargs.get(ruby.to_symbol("download_assets")) {
2026
+ Some(v) => bool::try_convert(v).map_err(|e| {
2027
+ magnus::Error::new(
2028
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2029
+ format!("invalid value for `download_assets`: {}", e),
2030
+ )
2031
+ })?,
2032
+ None => false,
2033
+ },
2034
+ asset_types: match kwargs.get(ruby.to_symbol("asset_types")) {
2035
+ Some(v) => <Vec<AssetCategory>>::try_convert(v).map_err(|e| {
2036
+ magnus::Error::new(
2037
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2038
+ format!("invalid value for `asset_types`: {}", e),
2039
+ )
2040
+ })?,
2041
+ None => Default::default(),
2042
+ },
2043
+ max_asset_size: match kwargs.get(ruby.to_symbol("max_asset_size")).filter(|v| !v.is_nil()) {
2044
+ Some(v) => Some(usize::try_convert(v).map_err(|e| {
2045
+ magnus::Error::new(
2046
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2047
+ format!("invalid value for `max_asset_size`: {}", e),
2048
+ )
2049
+ })?),
2050
+ None => None,
2051
+ },
2052
+ browser: match kwargs.get(ruby.to_symbol("browser")) {
2053
+ Some(v) => BrowserConfig::try_convert(v).map_err(|e| {
2054
+ magnus::Error::new(
2055
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2056
+ format!("invalid value for `browser`: {}", e),
2057
+ )
2058
+ })?,
2059
+ None => Default::default(),
2060
+ },
2061
+ proxy: match kwargs.get(ruby.to_symbol("proxy")).filter(|v| !v.is_nil()) {
2062
+ Some(v) => Some(ProxyConfig::try_convert(v).map_err(|e| {
2063
+ magnus::Error::new(
2064
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2065
+ format!("invalid value for `proxy`: {}", e),
2066
+ )
2067
+ })?),
2068
+ None => None,
2069
+ },
2070
+ user_agents: match kwargs.get(ruby.to_symbol("user_agents")) {
2071
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
2072
+ magnus::Error::new(
2073
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2074
+ format!("invalid value for `user_agents`: {}", e),
2075
+ )
2076
+ })?,
2077
+ None => Default::default(),
2078
+ },
2079
+ capture_screenshot: match kwargs.get(ruby.to_symbol("capture_screenshot")) {
2080
+ Some(v) => bool::try_convert(v).map_err(|e| {
2081
+ magnus::Error::new(
2082
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2083
+ format!("invalid value for `capture_screenshot`: {}", e),
2084
+ )
2085
+ })?,
2086
+ None => false,
2087
+ },
2088
+ follow_document_urls: match kwargs.get(ruby.to_symbol("follow_document_urls")) {
2089
+ Some(v) => bool::try_convert(v).map_err(|e| {
2090
+ magnus::Error::new(
2091
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2092
+ format!("invalid value for `follow_document_urls`: {}", e),
2093
+ )
2094
+ })?,
2095
+ None => false,
2096
+ },
2097
+ document_url_depth: match kwargs.get(ruby.to_symbol("document_url_depth")).filter(|v| !v.is_nil()) {
2098
+ Some(v) => Some(u32::try_convert(v).map_err(|e| {
2099
+ magnus::Error::new(
2100
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2101
+ format!("invalid value for `document_url_depth`: {}", e),
2102
+ )
2103
+ })?),
2104
+ None => None,
2105
+ },
2106
+ download_documents: match kwargs.get(ruby.to_symbol("download_documents")) {
2107
+ Some(v) => bool::try_convert(v).map_err(|e| {
2108
+ magnus::Error::new(
2109
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2110
+ format!("invalid value for `download_documents`: {}", e),
2111
+ )
2112
+ })?,
2113
+ None => true,
2114
+ },
2115
+ document_max_size: match kwargs.get(ruby.to_symbol("document_max_size")).filter(|v| !v.is_nil()) {
2116
+ Some(v) => Some(usize::try_convert(v).map_err(|e| {
2117
+ magnus::Error::new(
2118
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2119
+ format!("invalid value for `document_max_size`: {}", e),
2120
+ )
2121
+ })?),
2122
+ None => None,
2123
+ },
2124
+ document_mime_types: match kwargs.get(ruby.to_symbol("document_mime_types")) {
2125
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
2126
+ magnus::Error::new(
2127
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2128
+ format!("invalid value for `document_mime_types`: {}", e),
2129
+ )
2130
+ })?,
2131
+ None => Default::default(),
2132
+ },
2133
+ document_output_dir: match kwargs
1538
2134
  .get(ruby.to_symbol("document_output_dir"))
1539
- .and_then(|v| String::try_convert(v).ok()),
1540
- document_content_encoding: kwargs
2135
+ .filter(|v| !v.is_nil())
2136
+ {
2137
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
2138
+ magnus::Error::new(
2139
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2140
+ format!("invalid value for `document_output_dir`: {}", e),
2141
+ )
2142
+ })?),
2143
+ None => None,
2144
+ },
2145
+ document_content_encoding: match kwargs
1541
2146
  .get(ruby.to_symbol("document_content_encoding"))
1542
- .and_then(|v| DocumentContentEncoding::try_convert(v).ok()),
1543
- warc_output: kwargs
1544
- .get(ruby.to_symbol("warc_output"))
1545
- .and_then(|v| String::try_convert(v).ok()),
1546
- browser_profile: kwargs
1547
- .get(ruby.to_symbol("browser_profile"))
1548
- .and_then(|v| String::try_convert(v).ok()),
1549
- save_browser_profile: kwargs
1550
- .get(ruby.to_symbol("save_browser_profile"))
1551
- .and_then(|v| bool::try_convert(v).ok())
1552
- .unwrap_or(false),
1553
- ssrf: kwargs
1554
- .get(ruby.to_symbol("ssrf"))
1555
- .and_then(|v| SsrfPolicy::try_convert(v).ok())
1556
- .unwrap_or(crawlberg::SsrfPolicy::from_env().into()),
1557
- ssrf_deny_private_explicit: kwargs
2147
+ .filter(|v| !v.is_nil())
2148
+ {
2149
+ Some(v) => Some(DocumentContentEncoding::try_convert(v).map_err(|e| {
2150
+ magnus::Error::new(
2151
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2152
+ format!("invalid value for `document_content_encoding`: {}", e),
2153
+ )
2154
+ })?),
2155
+ None => None,
2156
+ },
2157
+ warc_output: match kwargs.get(ruby.to_symbol("warc_output")).filter(|v| !v.is_nil()) {
2158
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
2159
+ magnus::Error::new(
2160
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2161
+ format!("invalid value for `warc_output`: {}", e),
2162
+ )
2163
+ })?),
2164
+ None => None,
2165
+ },
2166
+ browser_profile: match kwargs.get(ruby.to_symbol("browser_profile")).filter(|v| !v.is_nil()) {
2167
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
2168
+ magnus::Error::new(
2169
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2170
+ format!("invalid value for `browser_profile`: {}", e),
2171
+ )
2172
+ })?),
2173
+ None => None,
2174
+ },
2175
+ save_browser_profile: match kwargs.get(ruby.to_symbol("save_browser_profile")) {
2176
+ Some(v) => bool::try_convert(v).map_err(|e| {
2177
+ magnus::Error::new(
2178
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2179
+ format!("invalid value for `save_browser_profile`: {}", e),
2180
+ )
2181
+ })?,
2182
+ None => false,
2183
+ },
2184
+ ssrf: match kwargs.get(ruby.to_symbol("ssrf")) {
2185
+ Some(v) => SsrfPolicy::try_convert(v).map_err(|e| {
2186
+ magnus::Error::new(
2187
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2188
+ format!("invalid value for `ssrf`: {}", e),
2189
+ )
2190
+ })?,
2191
+ None => crawlberg::SsrfPolicy::from_env().into(),
2192
+ },
2193
+ ssrf_deny_private_explicit: match kwargs
1558
2194
  .get(ruby.to_symbol("ssrf_deny_private_explicit"))
1559
- .and_then(|v| bool::try_convert(v).ok()),
2195
+ .filter(|v| !v.is_nil())
2196
+ {
2197
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
2198
+ magnus::Error::new(
2199
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2200
+ format!("invalid value for `ssrf_deny_private_explicit`: {}", e),
2201
+ )
2202
+ })?),
2203
+ None => None,
2204
+ },
1560
2205
  })
1561
2206
  }
1562
2207
 
@@ -1890,12 +2535,22 @@ impl CrawlEngineHandle {
1890
2535
  use magnus::value::ReprValue;
1891
2536
  let inner = self.inner.clone();
1892
2537
  let core_req: crawlberg::CrawlStreamRequest = req.into();
1893
- let runtime = std::sync::Arc::new(tokio::runtime::Runtime::new().map_err(|e| {
1894
- magnus::Error::new(
1895
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
1896
- e.to_string(),
1897
- )
1898
- })?);
2538
+ // 16 MiB: tokio's ~2 MB default worker stack can overflow on a deep extraction
2539
+ // future (a nested archive member, a multi-stage OCR pipeline), and a stack overflow
2540
+ // aborts the process with SIGBUS instead of raising a catchable panic.
2541
+ const STREAM_RUNTIME_STACK_SIZE_BYTES: usize = 16 * 1024 * 1024;
2542
+ let runtime = std::sync::Arc::new(
2543
+ tokio::runtime::Builder::new_multi_thread()
2544
+ .enable_all()
2545
+ .thread_stack_size(STREAM_RUNTIME_STACK_SIZE_BYTES)
2546
+ .build()
2547
+ .map_err(|e| {
2548
+ magnus::Error::new(
2549
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
2550
+ e.to_string(),
2551
+ )
2552
+ })?,
2553
+ );
1899
2554
  let stream = runtime
1900
2555
  .block_on(async { inner.crawl_stream(core_req).await })
1901
2556
  .map_err(|e| {
@@ -1925,12 +2580,22 @@ impl CrawlEngineHandle {
1925
2580
  use magnus::value::ReprValue;
1926
2581
  let inner = self.inner.clone();
1927
2582
  let core_req: crawlberg::BatchCrawlStreamRequest = req.into();
1928
- let runtime = std::sync::Arc::new(tokio::runtime::Runtime::new().map_err(|e| {
1929
- magnus::Error::new(
1930
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
1931
- e.to_string(),
1932
- )
1933
- })?);
2583
+ // 16 MiB: tokio's ~2 MB default worker stack can overflow on a deep extraction
2584
+ // future (a nested archive member, a multi-stage OCR pipeline), and a stack overflow
2585
+ // aborts the process with SIGBUS instead of raising a catchable panic.
2586
+ const STREAM_RUNTIME_STACK_SIZE_BYTES: usize = 16 * 1024 * 1024;
2587
+ let runtime = std::sync::Arc::new(
2588
+ tokio::runtime::Builder::new_multi_thread()
2589
+ .enable_all()
2590
+ .thread_stack_size(STREAM_RUNTIME_STACK_SIZE_BYTES)
2591
+ .build()
2592
+ .map_err(|e| {
2593
+ magnus::Error::new(
2594
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
2595
+ e.to_string(),
2596
+ )
2597
+ })?,
2598
+ );
1934
2599
  let stream = runtime
1935
2600
  .block_on(async { inner.batch_crawl_stream(core_req).await })
1936
2601
  .map_err(|e| {
@@ -2022,85 +2687,198 @@ impl CrawlPageResult {
2022
2687
  let (kwargs_opt,) = args.optional;
2023
2688
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
2024
2689
  Ok(Self {
2025
- url: kwargs
2026
- .get(ruby.to_symbol("url"))
2027
- .and_then(|v| String::try_convert(v).ok())
2028
- .unwrap_or_default(),
2029
- normalized_url: kwargs
2030
- .get(ruby.to_symbol("normalized_url"))
2031
- .and_then(|v| String::try_convert(v).ok())
2032
- .unwrap_or_default(),
2033
- status_code: kwargs
2034
- .get(ruby.to_symbol("status_code"))
2035
- .and_then(|v| u16::try_convert(v).ok())
2036
- .unwrap_or_default(),
2037
- content_type: kwargs
2038
- .get(ruby.to_symbol("content_type"))
2039
- .and_then(|v| String::try_convert(v).ok())
2040
- .unwrap_or_default(),
2041
- html: kwargs
2042
- .get(ruby.to_symbol("html"))
2043
- .and_then(|v| String::try_convert(v).ok())
2044
- .unwrap_or_default(),
2045
- body_size: kwargs
2046
- .get(ruby.to_symbol("body_size"))
2047
- .and_then(|v| usize::try_convert(v).ok())
2048
- .unwrap_or_default(),
2049
- metadata: kwargs
2050
- .get(ruby.to_symbol("metadata"))
2051
- .and_then(|v| PageMetadata::try_convert(v).ok())
2052
- .unwrap_or_default(),
2053
- links: kwargs
2054
- .get(ruby.to_symbol("links"))
2055
- .and_then(|v| <Vec<LinkInfo>>::try_convert(v).ok())
2056
- .unwrap_or_default(),
2057
- images: kwargs
2058
- .get(ruby.to_symbol("images"))
2059
- .and_then(|v| <Vec<ImageInfo>>::try_convert(v).ok())
2060
- .unwrap_or_default(),
2061
- feeds: kwargs
2062
- .get(ruby.to_symbol("feeds"))
2063
- .and_then(|v| <Vec<FeedInfo>>::try_convert(v).ok())
2064
- .unwrap_or_default(),
2065
- json_ld: kwargs
2066
- .get(ruby.to_symbol("json_ld"))
2067
- .and_then(|v| <Vec<JsonLdEntry>>::try_convert(v).ok())
2068
- .unwrap_or_default(),
2069
- depth: kwargs
2070
- .get(ruby.to_symbol("depth"))
2071
- .and_then(|v| usize::try_convert(v).ok())
2072
- .unwrap_or_default(),
2073
- stayed_on_domain: kwargs
2074
- .get(ruby.to_symbol("stayed_on_domain"))
2075
- .and_then(|v| bool::try_convert(v).ok())
2076
- .unwrap_or_default(),
2077
- was_skipped: kwargs
2078
- .get(ruby.to_symbol("was_skipped"))
2079
- .and_then(|v| bool::try_convert(v).ok())
2080
- .unwrap_or_default(),
2081
- is_pdf: kwargs
2082
- .get(ruby.to_symbol("is_pdf"))
2083
- .and_then(|v| bool::try_convert(v).ok())
2084
- .unwrap_or_default(),
2085
- detected_charset: kwargs
2086
- .get(ruby.to_symbol("detected_charset"))
2087
- .and_then(|v| String::try_convert(v).ok()),
2088
- markdown: kwargs
2089
- .get(ruby.to_symbol("markdown"))
2090
- .and_then(|v| MarkdownResult::try_convert(v).ok()),
2091
- extracted_data: kwargs
2092
- .get(ruby.to_symbol("extracted_data"))
2093
- .and_then(|v| String::try_convert(v).ok()),
2094
- extraction_meta: kwargs
2095
- .get(ruby.to_symbol("extraction_meta"))
2096
- .and_then(|v| ExtractionMeta::try_convert(v).ok()),
2097
- downloaded_document: kwargs
2690
+ url: match kwargs.get(ruby.to_symbol("url")) {
2691
+ Some(v) => String::try_convert(v).map_err(|e| {
2692
+ magnus::Error::new(
2693
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2694
+ format!("invalid value for `url`: {}", e),
2695
+ )
2696
+ })?,
2697
+ None => Default::default(),
2698
+ },
2699
+ normalized_url: match kwargs.get(ruby.to_symbol("normalized_url")) {
2700
+ Some(v) => String::try_convert(v).map_err(|e| {
2701
+ magnus::Error::new(
2702
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2703
+ format!("invalid value for `normalized_url`: {}", e),
2704
+ )
2705
+ })?,
2706
+ None => Default::default(),
2707
+ },
2708
+ status_code: match kwargs.get(ruby.to_symbol("status_code")) {
2709
+ Some(v) => u16::try_convert(v).map_err(|e| {
2710
+ magnus::Error::new(
2711
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2712
+ format!("invalid value for `status_code`: {}", e),
2713
+ )
2714
+ })?,
2715
+ None => Default::default(),
2716
+ },
2717
+ content_type: match kwargs.get(ruby.to_symbol("content_type")) {
2718
+ Some(v) => String::try_convert(v).map_err(|e| {
2719
+ magnus::Error::new(
2720
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2721
+ format!("invalid value for `content_type`: {}", e),
2722
+ )
2723
+ })?,
2724
+ None => Default::default(),
2725
+ },
2726
+ html: match kwargs.get(ruby.to_symbol("html")) {
2727
+ Some(v) => String::try_convert(v).map_err(|e| {
2728
+ magnus::Error::new(
2729
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2730
+ format!("invalid value for `html`: {}", e),
2731
+ )
2732
+ })?,
2733
+ None => Default::default(),
2734
+ },
2735
+ body_size: match kwargs.get(ruby.to_symbol("body_size")) {
2736
+ Some(v) => usize::try_convert(v).map_err(|e| {
2737
+ magnus::Error::new(
2738
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2739
+ format!("invalid value for `body_size`: {}", e),
2740
+ )
2741
+ })?,
2742
+ None => Default::default(),
2743
+ },
2744
+ metadata: match kwargs.get(ruby.to_symbol("metadata")) {
2745
+ Some(v) => PageMetadata::try_convert(v).map_err(|e| {
2746
+ magnus::Error::new(
2747
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2748
+ format!("invalid value for `metadata`: {}", e),
2749
+ )
2750
+ })?,
2751
+ None => Default::default(),
2752
+ },
2753
+ links: match kwargs.get(ruby.to_symbol("links")) {
2754
+ Some(v) => <Vec<LinkInfo>>::try_convert(v).map_err(|e| {
2755
+ magnus::Error::new(
2756
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2757
+ format!("invalid value for `links`: {}", e),
2758
+ )
2759
+ })?,
2760
+ None => Default::default(),
2761
+ },
2762
+ images: match kwargs.get(ruby.to_symbol("images")) {
2763
+ Some(v) => <Vec<ImageInfo>>::try_convert(v).map_err(|e| {
2764
+ magnus::Error::new(
2765
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2766
+ format!("invalid value for `images`: {}", e),
2767
+ )
2768
+ })?,
2769
+ None => Default::default(),
2770
+ },
2771
+ feeds: match kwargs.get(ruby.to_symbol("feeds")) {
2772
+ Some(v) => <Vec<FeedInfo>>::try_convert(v).map_err(|e| {
2773
+ magnus::Error::new(
2774
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2775
+ format!("invalid value for `feeds`: {}", e),
2776
+ )
2777
+ })?,
2778
+ None => Default::default(),
2779
+ },
2780
+ json_ld: match kwargs.get(ruby.to_symbol("json_ld")) {
2781
+ Some(v) => <Vec<JsonLdEntry>>::try_convert(v).map_err(|e| {
2782
+ magnus::Error::new(
2783
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2784
+ format!("invalid value for `json_ld`: {}", e),
2785
+ )
2786
+ })?,
2787
+ None => Default::default(),
2788
+ },
2789
+ depth: match kwargs.get(ruby.to_symbol("depth")) {
2790
+ Some(v) => usize::try_convert(v).map_err(|e| {
2791
+ magnus::Error::new(
2792
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2793
+ format!("invalid value for `depth`: {}", e),
2794
+ )
2795
+ })?,
2796
+ None => Default::default(),
2797
+ },
2798
+ stayed_on_domain: match kwargs.get(ruby.to_symbol("stayed_on_domain")) {
2799
+ Some(v) => bool::try_convert(v).map_err(|e| {
2800
+ magnus::Error::new(
2801
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2802
+ format!("invalid value for `stayed_on_domain`: {}", e),
2803
+ )
2804
+ })?,
2805
+ None => Default::default(),
2806
+ },
2807
+ was_skipped: match kwargs.get(ruby.to_symbol("was_skipped")) {
2808
+ Some(v) => bool::try_convert(v).map_err(|e| {
2809
+ magnus::Error::new(
2810
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2811
+ format!("invalid value for `was_skipped`: {}", e),
2812
+ )
2813
+ })?,
2814
+ None => Default::default(),
2815
+ },
2816
+ is_pdf: match kwargs.get(ruby.to_symbol("is_pdf")) {
2817
+ Some(v) => bool::try_convert(v).map_err(|e| {
2818
+ magnus::Error::new(
2819
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2820
+ format!("invalid value for `is_pdf`: {}", e),
2821
+ )
2822
+ })?,
2823
+ None => Default::default(),
2824
+ },
2825
+ detected_charset: match kwargs.get(ruby.to_symbol("detected_charset")).filter(|v| !v.is_nil()) {
2826
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
2827
+ magnus::Error::new(
2828
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2829
+ format!("invalid value for `detected_charset`: {}", e),
2830
+ )
2831
+ })?),
2832
+ None => None,
2833
+ },
2834
+ markdown: match kwargs.get(ruby.to_symbol("markdown")).filter(|v| !v.is_nil()) {
2835
+ Some(v) => Some(MarkdownResult::try_convert(v).map_err(|e| {
2836
+ magnus::Error::new(
2837
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2838
+ format!("invalid value for `markdown`: {}", e),
2839
+ )
2840
+ })?),
2841
+ None => None,
2842
+ },
2843
+ extracted_data: match kwargs.get(ruby.to_symbol("extracted_data")).filter(|v| !v.is_nil()) {
2844
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
2845
+ magnus::Error::new(
2846
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2847
+ format!("invalid value for `extracted_data`: {}", e),
2848
+ )
2849
+ })?),
2850
+ None => None,
2851
+ },
2852
+ extraction_meta: match kwargs.get(ruby.to_symbol("extraction_meta")).filter(|v| !v.is_nil()) {
2853
+ Some(v) => Some(ExtractionMeta::try_convert(v).map_err(|e| {
2854
+ magnus::Error::new(
2855
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2856
+ format!("invalid value for `extraction_meta`: {}", e),
2857
+ )
2858
+ })?),
2859
+ None => None,
2860
+ },
2861
+ downloaded_document: match kwargs
2098
2862
  .get(ruby.to_symbol("downloaded_document"))
2099
- .and_then(|v| DownloadedDocument::try_convert(v).ok()),
2100
- browser_used: kwargs
2101
- .get(ruby.to_symbol("browser_used"))
2102
- .and_then(|v| bool::try_convert(v).ok())
2103
- .unwrap_or_default(),
2863
+ .filter(|v| !v.is_nil())
2864
+ {
2865
+ Some(v) => Some(DownloadedDocument::try_convert(v).map_err(|e| {
2866
+ magnus::Error::new(
2867
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2868
+ format!("invalid value for `downloaded_document`: {}", e),
2869
+ )
2870
+ })?),
2871
+ None => None,
2872
+ },
2873
+ browser_used: match kwargs.get(ruby.to_symbol("browser_used")) {
2874
+ Some(v) => bool::try_convert(v).map_err(|e| {
2875
+ magnus::Error::new(
2876
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2877
+ format!("invalid value for `browser_used`: {}", e),
2878
+ )
2879
+ })?,
2880
+ None => Default::default(),
2881
+ },
2104
2882
  })
2105
2883
  }
2106
2884
 
@@ -2244,37 +3022,78 @@ impl CrawlResult {
2244
3022
  let (kwargs_opt,) = args.optional;
2245
3023
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
2246
3024
  Ok(Self {
2247
- pages: kwargs
2248
- .get(ruby.to_symbol("pages"))
2249
- .and_then(|v| <Vec<CrawlPageResult>>::try_convert(v).ok())
2250
- .unwrap_or_default(),
2251
- final_url: kwargs
2252
- .get(ruby.to_symbol("final_url"))
2253
- .and_then(|v| String::try_convert(v).ok())
2254
- .unwrap_or_default(),
2255
- redirect_count: kwargs
2256
- .get(ruby.to_symbol("redirect_count"))
2257
- .and_then(|v| usize::try_convert(v).ok())
2258
- .unwrap_or_default(),
2259
- was_skipped: kwargs
2260
- .get(ruby.to_symbol("was_skipped"))
2261
- .and_then(|v| bool::try_convert(v).ok())
2262
- .unwrap_or_default(),
2263
- error: kwargs
2264
- .get(ruby.to_symbol("error"))
2265
- .and_then(|v| String::try_convert(v).ok()),
2266
- cookies: kwargs
2267
- .get(ruby.to_symbol("cookies"))
2268
- .and_then(|v| <Vec<CookieInfo>>::try_convert(v).ok())
2269
- .unwrap_or_default(),
2270
- stayed_on_domain: kwargs
2271
- .get(ruby.to_symbol("stayed_on_domain"))
2272
- .and_then(|v| bool::try_convert(v).ok())
2273
- .unwrap_or_default(),
2274
- browser_used: kwargs
2275
- .get(ruby.to_symbol("browser_used"))
2276
- .and_then(|v| bool::try_convert(v).ok())
2277
- .unwrap_or_default(),
3025
+ pages: match kwargs.get(ruby.to_symbol("pages")) {
3026
+ Some(v) => <Vec<CrawlPageResult>>::try_convert(v).map_err(|e| {
3027
+ magnus::Error::new(
3028
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3029
+ format!("invalid value for `pages`: {}", e),
3030
+ )
3031
+ })?,
3032
+ None => Default::default(),
3033
+ },
3034
+ final_url: match kwargs.get(ruby.to_symbol("final_url")) {
3035
+ Some(v) => String::try_convert(v).map_err(|e| {
3036
+ magnus::Error::new(
3037
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3038
+ format!("invalid value for `final_url`: {}", e),
3039
+ )
3040
+ })?,
3041
+ None => Default::default(),
3042
+ },
3043
+ redirect_count: match kwargs.get(ruby.to_symbol("redirect_count")) {
3044
+ Some(v) => usize::try_convert(v).map_err(|e| {
3045
+ magnus::Error::new(
3046
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3047
+ format!("invalid value for `redirect_count`: {}", e),
3048
+ )
3049
+ })?,
3050
+ None => Default::default(),
3051
+ },
3052
+ was_skipped: match kwargs.get(ruby.to_symbol("was_skipped")) {
3053
+ Some(v) => bool::try_convert(v).map_err(|e| {
3054
+ magnus::Error::new(
3055
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3056
+ format!("invalid value for `was_skipped`: {}", e),
3057
+ )
3058
+ })?,
3059
+ None => Default::default(),
3060
+ },
3061
+ error: match kwargs.get(ruby.to_symbol("error")).filter(|v| !v.is_nil()) {
3062
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3063
+ magnus::Error::new(
3064
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3065
+ format!("invalid value for `error`: {}", e),
3066
+ )
3067
+ })?),
3068
+ None => None,
3069
+ },
3070
+ cookies: match kwargs.get(ruby.to_symbol("cookies")) {
3071
+ Some(v) => <Vec<CookieInfo>>::try_convert(v).map_err(|e| {
3072
+ magnus::Error::new(
3073
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3074
+ format!("invalid value for `cookies`: {}", e),
3075
+ )
3076
+ })?,
3077
+ None => Default::default(),
3078
+ },
3079
+ stayed_on_domain: match kwargs.get(ruby.to_symbol("stayed_on_domain")) {
3080
+ Some(v) => bool::try_convert(v).map_err(|e| {
3081
+ magnus::Error::new(
3082
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3083
+ format!("invalid value for `stayed_on_domain`: {}", e),
3084
+ )
3085
+ })?,
3086
+ None => Default::default(),
3087
+ },
3088
+ browser_used: match kwargs.get(ruby.to_symbol("browser_used")) {
3089
+ Some(v) => bool::try_convert(v).map_err(|e| {
3090
+ magnus::Error::new(
3091
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3092
+ format!("invalid value for `browser_used`: {}", e),
3093
+ )
3094
+ })?,
3095
+ None => Default::default(),
3096
+ },
2278
3097
  })
2279
3098
  }
2280
3099
 
@@ -2343,8 +3162,10 @@ pub struct CrawlStreamRequest {
2343
3162
  url: String,
2344
3163
  }
2345
3164
 
3165
+ #[cfg(not(target_arch = "wasm32"))]
2346
3166
  unsafe impl IntoValueFromNative for CrawlStreamRequest {}
2347
3167
 
3168
+ #[cfg(not(target_arch = "wasm32"))]
2348
3169
  impl magnus::TryConvert for CrawlStreamRequest {
2349
3170
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
2350
3171
  if let Ok(r) = <&CrawlStreamRequest as magnus::TryConvert>::try_convert(val) {
@@ -2369,6 +3190,7 @@ impl magnus::TryConvert for CrawlStreamRequest {
2369
3190
  }
2370
3191
  }
2371
3192
 
3193
+ #[cfg(not(target_arch = "wasm32"))]
2372
3194
  unsafe impl TryConvertOwned for CrawlStreamRequest {}
2373
3195
 
2374
3196
  #[cfg(not(target_arch = "wasm32"))]
@@ -2386,10 +3208,15 @@ impl CrawlStreamRequest {
2386
3208
  let (kwargs_opt,) = args.optional;
2387
3209
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
2388
3210
  Ok(Self {
2389
- url: kwargs
2390
- .get(ruby.to_symbol("url"))
2391
- .and_then(|v| String::try_convert(v).ok())
2392
- .unwrap_or_default(),
3211
+ url: match kwargs.get(ruby.to_symbol("url")) {
3212
+ Some(v) => String::try_convert(v).map_err(|e| {
3213
+ magnus::Error::new(
3214
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3215
+ format!("invalid value for `url`: {}", e),
3216
+ )
3217
+ })?,
3218
+ None => Default::default(),
3219
+ },
2393
3220
  })
2394
3221
  }
2395
3222
 
@@ -2451,28 +3278,60 @@ impl DownloadedAsset {
2451
3278
  let (kwargs_opt,) = args.optional;
2452
3279
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
2453
3280
  Ok(Self {
2454
- url: kwargs
2455
- .get(ruby.to_symbol("url"))
2456
- .and_then(|v| String::try_convert(v).ok())
2457
- .unwrap_or_default(),
2458
- content_hash: kwargs
2459
- .get(ruby.to_symbol("content_hash"))
2460
- .and_then(|v| String::try_convert(v).ok())
2461
- .unwrap_or_default(),
2462
- mime_type: kwargs
2463
- .get(ruby.to_symbol("mime_type"))
2464
- .and_then(|v| String::try_convert(v).ok()),
2465
- size: kwargs
2466
- .get(ruby.to_symbol("size"))
2467
- .and_then(|v| usize::try_convert(v).ok())
2468
- .unwrap_or_default(),
2469
- asset_category: kwargs
2470
- .get(ruby.to_symbol("asset_category"))
2471
- .and_then(|v| AssetCategory::try_convert(v).ok())
2472
- .unwrap_or(AssetCategory::Image),
2473
- html_tag: kwargs
2474
- .get(ruby.to_symbol("html_tag"))
2475
- .and_then(|v| String::try_convert(v).ok()),
3281
+ url: match kwargs.get(ruby.to_symbol("url")) {
3282
+ Some(v) => String::try_convert(v).map_err(|e| {
3283
+ magnus::Error::new(
3284
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3285
+ format!("invalid value for `url`: {}", e),
3286
+ )
3287
+ })?,
3288
+ None => Default::default(),
3289
+ },
3290
+ content_hash: match kwargs.get(ruby.to_symbol("content_hash")) {
3291
+ Some(v) => String::try_convert(v).map_err(|e| {
3292
+ magnus::Error::new(
3293
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3294
+ format!("invalid value for `content_hash`: {}", e),
3295
+ )
3296
+ })?,
3297
+ None => Default::default(),
3298
+ },
3299
+ mime_type: match kwargs.get(ruby.to_symbol("mime_type")).filter(|v| !v.is_nil()) {
3300
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3301
+ magnus::Error::new(
3302
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3303
+ format!("invalid value for `mime_type`: {}", e),
3304
+ )
3305
+ })?),
3306
+ None => None,
3307
+ },
3308
+ size: match kwargs.get(ruby.to_symbol("size")) {
3309
+ Some(v) => usize::try_convert(v).map_err(|e| {
3310
+ magnus::Error::new(
3311
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3312
+ format!("invalid value for `size`: {}", e),
3313
+ )
3314
+ })?,
3315
+ None => Default::default(),
3316
+ },
3317
+ asset_category: match kwargs.get(ruby.to_symbol("asset_category")) {
3318
+ Some(v) => AssetCategory::try_convert(v).map_err(|e| {
3319
+ magnus::Error::new(
3320
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3321
+ format!("invalid value for `asset_category`: {}", e),
3322
+ )
3323
+ })?,
3324
+ None => AssetCategory::Image,
3325
+ },
3326
+ html_tag: match kwargs.get(ruby.to_symbol("html_tag")).filter(|v| !v.is_nil()) {
3327
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3328
+ magnus::Error::new(
3329
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3330
+ format!("invalid value for `html_tag`: {}", e),
3331
+ )
3332
+ })?),
3333
+ None => None,
3334
+ },
2476
3335
  })
2477
3336
  }
2478
3337
 
@@ -2565,39 +3424,87 @@ impl DownloadedDocument {
2565
3424
  let (kwargs_opt,) = args.optional;
2566
3425
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
2567
3426
  Ok(Self {
2568
- url: kwargs
2569
- .get(ruby.to_symbol("url"))
2570
- .and_then(|v| String::try_convert(v).ok())
2571
- .unwrap_or_default(),
2572
- mime_type: kwargs
2573
- .get(ruby.to_symbol("mime_type"))
2574
- .and_then(|v| String::try_convert(v).ok())
2575
- .unwrap_or_default(),
2576
- size: kwargs
2577
- .get(ruby.to_symbol("size"))
2578
- .and_then(|v| usize::try_convert(v).ok())
2579
- .unwrap_or_default(),
2580
- filename: kwargs
2581
- .get(ruby.to_symbol("filename"))
2582
- .and_then(|v| String::try_convert(v).ok()),
2583
- content_hash: kwargs
2584
- .get(ruby.to_symbol("content_hash"))
2585
- .and_then(|v| String::try_convert(v).ok())
2586
- .unwrap_or_default(),
2587
- headers: kwargs
2588
- .get(ruby.to_symbol("headers"))
2589
- .and_then(|v| <HashMap<String, String>>::try_convert(v).ok())
2590
- .unwrap_or_default(),
2591
- truncated: kwargs
2592
- .get(ruby.to_symbol("truncated"))
2593
- .and_then(|v| bool::try_convert(v).ok())
2594
- .unwrap_or_default(),
2595
- content_path: kwargs
2596
- .get(ruby.to_symbol("content_path"))
2597
- .and_then(|v| String::try_convert(v).ok()),
2598
- content_base64: kwargs
2599
- .get(ruby.to_symbol("content_base64"))
2600
- .and_then(|v| String::try_convert(v).ok()),
3427
+ url: match kwargs.get(ruby.to_symbol("url")) {
3428
+ Some(v) => String::try_convert(v).map_err(|e| {
3429
+ magnus::Error::new(
3430
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3431
+ format!("invalid value for `url`: {}", e),
3432
+ )
3433
+ })?,
3434
+ None => Default::default(),
3435
+ },
3436
+ mime_type: match kwargs.get(ruby.to_symbol("mime_type")) {
3437
+ Some(v) => String::try_convert(v).map_err(|e| {
3438
+ magnus::Error::new(
3439
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3440
+ format!("invalid value for `mime_type`: {}", e),
3441
+ )
3442
+ })?,
3443
+ None => Default::default(),
3444
+ },
3445
+ size: match kwargs.get(ruby.to_symbol("size")) {
3446
+ Some(v) => usize::try_convert(v).map_err(|e| {
3447
+ magnus::Error::new(
3448
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3449
+ format!("invalid value for `size`: {}", e),
3450
+ )
3451
+ })?,
3452
+ None => Default::default(),
3453
+ },
3454
+ filename: match kwargs.get(ruby.to_symbol("filename")).filter(|v| !v.is_nil()) {
3455
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3456
+ magnus::Error::new(
3457
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3458
+ format!("invalid value for `filename`: {}", e),
3459
+ )
3460
+ })?),
3461
+ None => None,
3462
+ },
3463
+ content_hash: match kwargs.get(ruby.to_symbol("content_hash")) {
3464
+ Some(v) => String::try_convert(v).map_err(|e| {
3465
+ magnus::Error::new(
3466
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3467
+ format!("invalid value for `content_hash`: {}", e),
3468
+ )
3469
+ })?,
3470
+ None => Default::default(),
3471
+ },
3472
+ headers: match kwargs.get(ruby.to_symbol("headers")) {
3473
+ Some(v) => <HashMap<String, String>>::try_convert(v).map_err(|e| {
3474
+ magnus::Error::new(
3475
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3476
+ format!("invalid value for `headers`: {}", e),
3477
+ )
3478
+ })?,
3479
+ None => Default::default(),
3480
+ },
3481
+ truncated: match kwargs.get(ruby.to_symbol("truncated")) {
3482
+ Some(v) => bool::try_convert(v).map_err(|e| {
3483
+ magnus::Error::new(
3484
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3485
+ format!("invalid value for `truncated`: {}", e),
3486
+ )
3487
+ })?,
3488
+ None => Default::default(),
3489
+ },
3490
+ content_path: match kwargs.get(ruby.to_symbol("content_path")).filter(|v| !v.is_nil()) {
3491
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3492
+ magnus::Error::new(
3493
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3494
+ format!("invalid value for `content_path`: {}", e),
3495
+ )
3496
+ })?),
3497
+ None => None,
3498
+ },
3499
+ content_base64: match kwargs.get(ruby.to_symbol("content_base64")).filter(|v| !v.is_nil()) {
3500
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3501
+ magnus::Error::new(
3502
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3503
+ format!("invalid value for `content_base64`: {}", e),
3504
+ )
3505
+ })?),
3506
+ None => None,
3507
+ },
2601
3508
  })
2602
3509
  }
2603
3510
 
@@ -2690,22 +3597,51 @@ impl ExtractionMeta {
2690
3597
  let (kwargs_opt,) = args.optional;
2691
3598
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
2692
3599
  Ok(Self {
2693
- cost: kwargs
2694
- .get(ruby.to_symbol("cost"))
2695
- .and_then(|v| f64::try_convert(v).ok()),
2696
- prompt_tokens: kwargs
2697
- .get(ruby.to_symbol("prompt_tokens"))
2698
- .and_then(|v| u64::try_convert(v).ok()),
2699
- completion_tokens: kwargs
2700
- .get(ruby.to_symbol("completion_tokens"))
2701
- .and_then(|v| u64::try_convert(v).ok()),
2702
- model: kwargs
2703
- .get(ruby.to_symbol("model"))
2704
- .and_then(|v| String::try_convert(v).ok()),
2705
- chunks_processed: kwargs
2706
- .get(ruby.to_symbol("chunks_processed"))
2707
- .and_then(|v| usize::try_convert(v).ok())
2708
- .unwrap_or_default(),
3600
+ cost: match kwargs.get(ruby.to_symbol("cost")).filter(|v| !v.is_nil()) {
3601
+ Some(v) => Some(f64::try_convert(v).map_err(|e| {
3602
+ magnus::Error::new(
3603
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3604
+ format!("invalid value for `cost`: {}", e),
3605
+ )
3606
+ })?),
3607
+ None => None,
3608
+ },
3609
+ prompt_tokens: match kwargs.get(ruby.to_symbol("prompt_tokens")).filter(|v| !v.is_nil()) {
3610
+ Some(v) => Some(u64::try_convert(v).map_err(|e| {
3611
+ magnus::Error::new(
3612
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3613
+ format!("invalid value for `prompt_tokens`: {}", e),
3614
+ )
3615
+ })?),
3616
+ None => None,
3617
+ },
3618
+ completion_tokens: match kwargs.get(ruby.to_symbol("completion_tokens")).filter(|v| !v.is_nil()) {
3619
+ Some(v) => Some(u64::try_convert(v).map_err(|e| {
3620
+ magnus::Error::new(
3621
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3622
+ format!("invalid value for `completion_tokens`: {}", e),
3623
+ )
3624
+ })?),
3625
+ None => None,
3626
+ },
3627
+ model: match kwargs.get(ruby.to_symbol("model")).filter(|v| !v.is_nil()) {
3628
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3629
+ magnus::Error::new(
3630
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3631
+ format!("invalid value for `model`: {}", e),
3632
+ )
3633
+ })?),
3634
+ None => None,
3635
+ },
3636
+ chunks_processed: match kwargs.get(ruby.to_symbol("chunks_processed")) {
3637
+ Some(v) => usize::try_convert(v).map_err(|e| {
3638
+ magnus::Error::new(
3639
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3640
+ format!("invalid value for `chunks_processed`: {}", e),
3641
+ )
3642
+ })?,
3643
+ None => Default::default(),
3644
+ },
2709
3645
  })
2710
3646
  }
2711
3647
 
@@ -2781,20 +3717,42 @@ impl FaviconInfo {
2781
3717
  let (kwargs_opt,) = args.optional;
2782
3718
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
2783
3719
  Ok(Self {
2784
- url: kwargs
2785
- .get(ruby.to_symbol("url"))
2786
- .and_then(|v| String::try_convert(v).ok())
2787
- .unwrap_or_default(),
2788
- rel: kwargs
2789
- .get(ruby.to_symbol("rel"))
2790
- .and_then(|v| String::try_convert(v).ok())
2791
- .unwrap_or_default(),
2792
- sizes: kwargs
2793
- .get(ruby.to_symbol("sizes"))
2794
- .and_then(|v| String::try_convert(v).ok()),
2795
- mime_type: kwargs
2796
- .get(ruby.to_symbol("mime_type"))
2797
- .and_then(|v| String::try_convert(v).ok()),
3720
+ url: match kwargs.get(ruby.to_symbol("url")) {
3721
+ Some(v) => String::try_convert(v).map_err(|e| {
3722
+ magnus::Error::new(
3723
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3724
+ format!("invalid value for `url`: {}", e),
3725
+ )
3726
+ })?,
3727
+ None => Default::default(),
3728
+ },
3729
+ rel: match kwargs.get(ruby.to_symbol("rel")) {
3730
+ Some(v) => String::try_convert(v).map_err(|e| {
3731
+ magnus::Error::new(
3732
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3733
+ format!("invalid value for `rel`: {}", e),
3734
+ )
3735
+ })?,
3736
+ None => Default::default(),
3737
+ },
3738
+ sizes: match kwargs.get(ruby.to_symbol("sizes")).filter(|v| !v.is_nil()) {
3739
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3740
+ magnus::Error::new(
3741
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3742
+ format!("invalid value for `sizes`: {}", e),
3743
+ )
3744
+ })?),
3745
+ None => None,
3746
+ },
3747
+ mime_type: match kwargs.get(ruby.to_symbol("mime_type")).filter(|v| !v.is_nil()) {
3748
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3749
+ magnus::Error::new(
3750
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3751
+ format!("invalid value for `mime_type`: {}", e),
3752
+ )
3753
+ })?),
3754
+ None => None,
3755
+ },
2798
3756
  })
2799
3757
  }
2800
3758
 
@@ -2865,17 +3823,33 @@ impl FeedInfo {
2865
3823
  let (kwargs_opt,) = args.optional;
2866
3824
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
2867
3825
  Ok(Self {
2868
- url: kwargs
2869
- .get(ruby.to_symbol("url"))
2870
- .and_then(|v| String::try_convert(v).ok())
2871
- .unwrap_or_default(),
2872
- title: kwargs
2873
- .get(ruby.to_symbol("title"))
2874
- .and_then(|v| String::try_convert(v).ok()),
2875
- feed_type: kwargs
2876
- .get(ruby.to_symbol("feed_type"))
2877
- .and_then(|v| FeedType::try_convert(v).ok())
2878
- .unwrap_or(FeedType::Rss),
3826
+ url: match kwargs.get(ruby.to_symbol("url")) {
3827
+ Some(v) => String::try_convert(v).map_err(|e| {
3828
+ magnus::Error::new(
3829
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3830
+ format!("invalid value for `url`: {}", e),
3831
+ )
3832
+ })?,
3833
+ None => Default::default(),
3834
+ },
3835
+ title: match kwargs.get(ruby.to_symbol("title")).filter(|v| !v.is_nil()) {
3836
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3837
+ magnus::Error::new(
3838
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3839
+ format!("invalid value for `title`: {}", e),
3840
+ )
3841
+ })?),
3842
+ None => None,
3843
+ },
3844
+ feed_type: match kwargs.get(ruby.to_symbol("feed_type")) {
3845
+ Some(v) => FeedType::try_convert(v).map_err(|e| {
3846
+ magnus::Error::new(
3847
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3848
+ format!("invalid value for `feed_type`: {}", e),
3849
+ )
3850
+ })?,
3851
+ None => FeedType::Rss,
3852
+ },
2879
3853
  })
2880
3854
  }
2881
3855
 
@@ -2941,14 +3915,24 @@ impl HeadingInfo {
2941
3915
  let (kwargs_opt,) = args.optional;
2942
3916
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
2943
3917
  Ok(Self {
2944
- level: kwargs
2945
- .get(ruby.to_symbol("level"))
2946
- .and_then(|v| u8::try_convert(v).ok())
2947
- .unwrap_or_default(),
2948
- text: kwargs
2949
- .get(ruby.to_symbol("text"))
2950
- .and_then(|v| String::try_convert(v).ok())
2951
- .unwrap_or_default(),
3918
+ level: match kwargs.get(ruby.to_symbol("level")) {
3919
+ Some(v) => u8::try_convert(v).map_err(|e| {
3920
+ magnus::Error::new(
3921
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3922
+ format!("invalid value for `level`: {}", e),
3923
+ )
3924
+ })?,
3925
+ None => Default::default(),
3926
+ },
3927
+ text: match kwargs.get(ruby.to_symbol("text")) {
3928
+ Some(v) => String::try_convert(v).map_err(|e| {
3929
+ magnus::Error::new(
3930
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3931
+ format!("invalid value for `text`: {}", e),
3932
+ )
3933
+ })?,
3934
+ None => Default::default(),
3935
+ },
2952
3936
  })
2953
3937
  }
2954
3938
 
@@ -3010,14 +3994,24 @@ impl HreflangEntry {
3010
3994
  let (kwargs_opt,) = args.optional;
3011
3995
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
3012
3996
  Ok(Self {
3013
- lang: kwargs
3014
- .get(ruby.to_symbol("lang"))
3015
- .and_then(|v| String::try_convert(v).ok())
3016
- .unwrap_or_default(),
3017
- url: kwargs
3018
- .get(ruby.to_symbol("url"))
3019
- .and_then(|v| String::try_convert(v).ok())
3020
- .unwrap_or_default(),
3997
+ lang: match kwargs.get(ruby.to_symbol("lang")) {
3998
+ Some(v) => String::try_convert(v).map_err(|e| {
3999
+ magnus::Error::new(
4000
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4001
+ format!("invalid value for `lang`: {}", e),
4002
+ )
4003
+ })?,
4004
+ None => Default::default(),
4005
+ },
4006
+ url: match kwargs.get(ruby.to_symbol("url")) {
4007
+ Some(v) => String::try_convert(v).map_err(|e| {
4008
+ magnus::Error::new(
4009
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4010
+ format!("invalid value for `url`: {}", e),
4011
+ )
4012
+ })?,
4013
+ None => Default::default(),
4014
+ },
3021
4015
  })
3022
4016
  }
3023
4017
 
@@ -3082,23 +4076,51 @@ impl ImageInfo {
3082
4076
  let (kwargs_opt,) = args.optional;
3083
4077
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
3084
4078
  Ok(Self {
3085
- url: kwargs
3086
- .get(ruby.to_symbol("url"))
3087
- .and_then(|v| String::try_convert(v).ok())
3088
- .unwrap_or_default(),
3089
- alt: kwargs
3090
- .get(ruby.to_symbol("alt"))
3091
- .and_then(|v| String::try_convert(v).ok()),
3092
- width: kwargs
3093
- .get(ruby.to_symbol("width"))
3094
- .and_then(|v| u32::try_convert(v).ok()),
3095
- height: kwargs
3096
- .get(ruby.to_symbol("height"))
3097
- .and_then(|v| u32::try_convert(v).ok()),
3098
- source: kwargs
3099
- .get(ruby.to_symbol("source"))
3100
- .and_then(|v| ImageSource::try_convert(v).ok())
3101
- .unwrap_or(ImageSource::Img),
4079
+ url: match kwargs.get(ruby.to_symbol("url")) {
4080
+ Some(v) => String::try_convert(v).map_err(|e| {
4081
+ magnus::Error::new(
4082
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4083
+ format!("invalid value for `url`: {}", e),
4084
+ )
4085
+ })?,
4086
+ None => Default::default(),
4087
+ },
4088
+ alt: match kwargs.get(ruby.to_symbol("alt")).filter(|v| !v.is_nil()) {
4089
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4090
+ magnus::Error::new(
4091
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4092
+ format!("invalid value for `alt`: {}", e),
4093
+ )
4094
+ })?),
4095
+ None => None,
4096
+ },
4097
+ width: match kwargs.get(ruby.to_symbol("width")).filter(|v| !v.is_nil()) {
4098
+ Some(v) => Some(u32::try_convert(v).map_err(|e| {
4099
+ magnus::Error::new(
4100
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4101
+ format!("invalid value for `width`: {}", e),
4102
+ )
4103
+ })?),
4104
+ None => None,
4105
+ },
4106
+ height: match kwargs.get(ruby.to_symbol("height")).filter(|v| !v.is_nil()) {
4107
+ Some(v) => Some(u32::try_convert(v).map_err(|e| {
4108
+ magnus::Error::new(
4109
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4110
+ format!("invalid value for `height`: {}", e),
4111
+ )
4112
+ })?),
4113
+ None => None,
4114
+ },
4115
+ source: match kwargs.get(ruby.to_symbol("source")) {
4116
+ Some(v) => ImageSource::try_convert(v).map_err(|e| {
4117
+ magnus::Error::new(
4118
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4119
+ format!("invalid value for `source`: {}", e),
4120
+ )
4121
+ })?,
4122
+ None => ImageSource::Img,
4123
+ },
3102
4124
  })
3103
4125
  }
3104
4126
 
@@ -3174,21 +4196,42 @@ impl InteractionResult {
3174
4196
  let (kwargs_opt,) = args.optional;
3175
4197
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
3176
4198
  Ok(Self {
3177
- action_results: kwargs
3178
- .get(ruby.to_symbol("action_results"))
3179
- .and_then(|v| <Vec<ActionResult>>::try_convert(v).ok())
3180
- .unwrap_or_default(),
3181
- final_html: kwargs
3182
- .get(ruby.to_symbol("final_html"))
3183
- .and_then(|v| String::try_convert(v).ok())
3184
- .unwrap_or_default(),
3185
- final_url: kwargs
3186
- .get(ruby.to_symbol("final_url"))
3187
- .and_then(|v| String::try_convert(v).ok())
3188
- .unwrap_or_default(),
3189
- screenshot_base64: kwargs
3190
- .get(ruby.to_symbol("screenshot_base64"))
3191
- .and_then(|v| String::try_convert(v).ok()),
4199
+ action_results: match kwargs.get(ruby.to_symbol("action_results")) {
4200
+ Some(v) => <Vec<ActionResult>>::try_convert(v).map_err(|e| {
4201
+ magnus::Error::new(
4202
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4203
+ format!("invalid value for `action_results`: {}", e),
4204
+ )
4205
+ })?,
4206
+ None => Default::default(),
4207
+ },
4208
+ final_html: match kwargs.get(ruby.to_symbol("final_html")) {
4209
+ Some(v) => String::try_convert(v).map_err(|e| {
4210
+ magnus::Error::new(
4211
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4212
+ format!("invalid value for `final_html`: {}", e),
4213
+ )
4214
+ })?,
4215
+ None => Default::default(),
4216
+ },
4217
+ final_url: match kwargs.get(ruby.to_symbol("final_url")) {
4218
+ Some(v) => String::try_convert(v).map_err(|e| {
4219
+ magnus::Error::new(
4220
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4221
+ format!("invalid value for `final_url`: {}", e),
4222
+ )
4223
+ })?,
4224
+ None => Default::default(),
4225
+ },
4226
+ screenshot_base64: match kwargs.get(ruby.to_symbol("screenshot_base64")).filter(|v| !v.is_nil()) {
4227
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4228
+ magnus::Error::new(
4229
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4230
+ format!("invalid value for `screenshot_base64`: {}", e),
4231
+ )
4232
+ })?),
4233
+ None => None,
4234
+ },
3192
4235
  })
3193
4236
  }
3194
4237
 
@@ -3259,17 +4302,33 @@ impl JsonLdEntry {
3259
4302
  let (kwargs_opt,) = args.optional;
3260
4303
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
3261
4304
  Ok(Self {
3262
- schema_type: kwargs
3263
- .get(ruby.to_symbol("schema_type"))
3264
- .and_then(|v| String::try_convert(v).ok())
3265
- .unwrap_or_default(),
3266
- name: kwargs
3267
- .get(ruby.to_symbol("name"))
3268
- .and_then(|v| String::try_convert(v).ok()),
3269
- raw: kwargs
3270
- .get(ruby.to_symbol("raw"))
3271
- .and_then(|v| String::try_convert(v).ok())
3272
- .unwrap_or_default(),
4305
+ schema_type: match kwargs.get(ruby.to_symbol("schema_type")) {
4306
+ Some(v) => String::try_convert(v).map_err(|e| {
4307
+ magnus::Error::new(
4308
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4309
+ format!("invalid value for `schema_type`: {}", e),
4310
+ )
4311
+ })?,
4312
+ None => Default::default(),
4313
+ },
4314
+ name: match kwargs.get(ruby.to_symbol("name")).filter(|v| !v.is_nil()) {
4315
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4316
+ magnus::Error::new(
4317
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4318
+ format!("invalid value for `name`: {}", e),
4319
+ )
4320
+ })?),
4321
+ None => None,
4322
+ },
4323
+ raw: match kwargs.get(ruby.to_symbol("raw")) {
4324
+ Some(v) => String::try_convert(v).map_err(|e| {
4325
+ magnus::Error::new(
4326
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4327
+ format!("invalid value for `raw`: {}", e),
4328
+ )
4329
+ })?,
4330
+ None => Default::default(),
4331
+ },
3273
4332
  })
3274
4333
  }
3275
4334
 
@@ -3338,25 +4397,51 @@ impl LinkInfo {
3338
4397
  let (kwargs_opt,) = args.optional;
3339
4398
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
3340
4399
  Ok(Self {
3341
- url: kwargs
3342
- .get(ruby.to_symbol("url"))
3343
- .and_then(|v| String::try_convert(v).ok())
3344
- .unwrap_or_default(),
3345
- text: kwargs
3346
- .get(ruby.to_symbol("text"))
3347
- .and_then(|v| String::try_convert(v).ok())
3348
- .unwrap_or_default(),
3349
- link_type: kwargs
3350
- .get(ruby.to_symbol("link_type"))
3351
- .and_then(|v| LinkType::try_convert(v).ok())
3352
- .unwrap_or(LinkType::Internal),
3353
- rel: kwargs
3354
- .get(ruby.to_symbol("rel"))
3355
- .and_then(|v| String::try_convert(v).ok()),
3356
- nofollow: kwargs
3357
- .get(ruby.to_symbol("nofollow"))
3358
- .and_then(|v| bool::try_convert(v).ok())
3359
- .unwrap_or_default(),
4400
+ url: match kwargs.get(ruby.to_symbol("url")) {
4401
+ Some(v) => String::try_convert(v).map_err(|e| {
4402
+ magnus::Error::new(
4403
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4404
+ format!("invalid value for `url`: {}", e),
4405
+ )
4406
+ })?,
4407
+ None => Default::default(),
4408
+ },
4409
+ text: match kwargs.get(ruby.to_symbol("text")) {
4410
+ Some(v) => String::try_convert(v).map_err(|e| {
4411
+ magnus::Error::new(
4412
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4413
+ format!("invalid value for `text`: {}", e),
4414
+ )
4415
+ })?,
4416
+ None => Default::default(),
4417
+ },
4418
+ link_type: match kwargs.get(ruby.to_symbol("link_type")) {
4419
+ Some(v) => LinkType::try_convert(v).map_err(|e| {
4420
+ magnus::Error::new(
4421
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4422
+ format!("invalid value for `link_type`: {}", e),
4423
+ )
4424
+ })?,
4425
+ None => LinkType::Internal,
4426
+ },
4427
+ rel: match kwargs.get(ruby.to_symbol("rel")).filter(|v| !v.is_nil()) {
4428
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4429
+ magnus::Error::new(
4430
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4431
+ format!("invalid value for `rel`: {}", e),
4432
+ )
4433
+ })?),
4434
+ None => None,
4435
+ },
4436
+ nofollow: match kwargs.get(ruby.to_symbol("nofollow")) {
4437
+ Some(v) => bool::try_convert(v).map_err(|e| {
4438
+ magnus::Error::new(
4439
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4440
+ format!("invalid value for `nofollow`: {}", e),
4441
+ )
4442
+ })?,
4443
+ None => Default::default(),
4444
+ },
3360
4445
  })
3361
4446
  }
3362
4447
 
@@ -3429,10 +4514,15 @@ impl MapResult {
3429
4514
  let (kwargs_opt,) = args.optional;
3430
4515
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
3431
4516
  Ok(Self {
3432
- urls: kwargs
3433
- .get(ruby.to_symbol("urls"))
3434
- .and_then(|v| <Vec<SitemapUrl>>::try_convert(v).ok())
3435
- .unwrap_or_default(),
4517
+ urls: match kwargs.get(ruby.to_symbol("urls")) {
4518
+ Some(v) => <Vec<SitemapUrl>>::try_convert(v).map_err(|e| {
4519
+ magnus::Error::new(
4520
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4521
+ format!("invalid value for `urls`: {}", e),
4522
+ )
4523
+ })?,
4524
+ None => Default::default(),
4525
+ },
3436
4526
  })
3437
4527
  }
3438
4528
 
@@ -3494,28 +4584,60 @@ impl MarkdownResult {
3494
4584
  let (kwargs_opt,) = args.optional;
3495
4585
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
3496
4586
  Ok(Self {
3497
- content: kwargs
3498
- .get(ruby.to_symbol("content"))
3499
- .and_then(|v| String::try_convert(v).ok())
3500
- .unwrap_or_default(),
3501
- document_structure: kwargs
3502
- .get(ruby.to_symbol("document_structure"))
3503
- .and_then(|v| String::try_convert(v).ok()),
3504
- tables: kwargs
3505
- .get(ruby.to_symbol("tables"))
3506
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
3507
- .unwrap_or_default(),
3508
- warnings: kwargs
3509
- .get(ruby.to_symbol("warnings"))
3510
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
3511
- .unwrap_or_default(),
3512
- citations: kwargs
3513
- .get(ruby.to_symbol("citations"))
3514
- .and_then(|v| bool::try_convert(v).ok())
3515
- .unwrap_or_default(),
3516
- fit_content: kwargs
3517
- .get(ruby.to_symbol("fit_content"))
3518
- .and_then(|v| String::try_convert(v).ok()),
4587
+ content: match kwargs.get(ruby.to_symbol("content")) {
4588
+ Some(v) => String::try_convert(v).map_err(|e| {
4589
+ magnus::Error::new(
4590
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4591
+ format!("invalid value for `content`: {}", e),
4592
+ )
4593
+ })?,
4594
+ None => Default::default(),
4595
+ },
4596
+ document_structure: match kwargs.get(ruby.to_symbol("document_structure")).filter(|v| !v.is_nil()) {
4597
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4598
+ magnus::Error::new(
4599
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4600
+ format!("invalid value for `document_structure`: {}", e),
4601
+ )
4602
+ })?),
4603
+ None => None,
4604
+ },
4605
+ tables: match kwargs.get(ruby.to_symbol("tables")) {
4606
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
4607
+ magnus::Error::new(
4608
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4609
+ format!("invalid value for `tables`: {}", e),
4610
+ )
4611
+ })?,
4612
+ None => Default::default(),
4613
+ },
4614
+ warnings: match kwargs.get(ruby.to_symbol("warnings")) {
4615
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
4616
+ magnus::Error::new(
4617
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4618
+ format!("invalid value for `warnings`: {}", e),
4619
+ )
4620
+ })?,
4621
+ None => Default::default(),
4622
+ },
4623
+ citations: match kwargs.get(ruby.to_symbol("citations")) {
4624
+ Some(v) => bool::try_convert(v).map_err(|e| {
4625
+ magnus::Error::new(
4626
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4627
+ format!("invalid value for `citations`: {}", e),
4628
+ )
4629
+ })?,
4630
+ None => Default::default(),
4631
+ },
4632
+ fit_content: match kwargs.get(ruby.to_symbol("fit_content")).filter(|v| !v.is_nil()) {
4633
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4634
+ magnus::Error::new(
4635
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4636
+ format!("invalid value for `fit_content`: {}", e),
4637
+ )
4638
+ })?),
4639
+ None => None,
4640
+ },
3519
4641
  })
3520
4642
  }
3521
4643
 
@@ -3639,135 +4761,399 @@ impl PageMetadata {
3639
4761
  let (kwargs_opt,) = args.optional;
3640
4762
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
3641
4763
  Ok(Self {
3642
- title: kwargs
3643
- .get(ruby.to_symbol("title"))
3644
- .and_then(|v| String::try_convert(v).ok()),
3645
- description: kwargs
3646
- .get(ruby.to_symbol("description"))
3647
- .and_then(|v| String::try_convert(v).ok()),
3648
- canonical_url: kwargs
3649
- .get(ruby.to_symbol("canonical_url"))
3650
- .and_then(|v| String::try_convert(v).ok()),
3651
- keywords: kwargs
3652
- .get(ruby.to_symbol("keywords"))
3653
- .and_then(|v| String::try_convert(v).ok()),
3654
- author: kwargs
3655
- .get(ruby.to_symbol("author"))
3656
- .and_then(|v| String::try_convert(v).ok()),
3657
- viewport: kwargs
3658
- .get(ruby.to_symbol("viewport"))
3659
- .and_then(|v| String::try_convert(v).ok()),
3660
- theme_color: kwargs
3661
- .get(ruby.to_symbol("theme_color"))
3662
- .and_then(|v| String::try_convert(v).ok()),
3663
- generator: kwargs
3664
- .get(ruby.to_symbol("generator"))
3665
- .and_then(|v| String::try_convert(v).ok()),
3666
- robots: kwargs
3667
- .get(ruby.to_symbol("robots"))
3668
- .and_then(|v| String::try_convert(v).ok()),
3669
- html_lang: kwargs
3670
- .get(ruby.to_symbol("html_lang"))
3671
- .and_then(|v| String::try_convert(v).ok()),
3672
- html_dir: kwargs
3673
- .get(ruby.to_symbol("html_dir"))
3674
- .and_then(|v| String::try_convert(v).ok()),
3675
- og_title: kwargs
3676
- .get(ruby.to_symbol("og_title"))
3677
- .and_then(|v| String::try_convert(v).ok()),
3678
- og_type: kwargs
3679
- .get(ruby.to_symbol("og_type"))
3680
- .and_then(|v| String::try_convert(v).ok()),
3681
- og_image: kwargs
3682
- .get(ruby.to_symbol("og_image"))
3683
- .and_then(|v| String::try_convert(v).ok()),
3684
- og_description: kwargs
3685
- .get(ruby.to_symbol("og_description"))
3686
- .and_then(|v| String::try_convert(v).ok()),
3687
- og_url: kwargs
3688
- .get(ruby.to_symbol("og_url"))
3689
- .and_then(|v| String::try_convert(v).ok()),
3690
- og_site_name: kwargs
3691
- .get(ruby.to_symbol("og_site_name"))
3692
- .and_then(|v| String::try_convert(v).ok()),
3693
- og_locale: kwargs
3694
- .get(ruby.to_symbol("og_locale"))
3695
- .and_then(|v| String::try_convert(v).ok()),
3696
- og_video: kwargs
3697
- .get(ruby.to_symbol("og_video"))
3698
- .and_then(|v| String::try_convert(v).ok()),
3699
- og_audio: kwargs
3700
- .get(ruby.to_symbol("og_audio"))
3701
- .and_then(|v| String::try_convert(v).ok()),
3702
- og_locale_alternates: kwargs
4764
+ title: match kwargs.get(ruby.to_symbol("title")).filter(|v| !v.is_nil()) {
4765
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4766
+ magnus::Error::new(
4767
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4768
+ format!("invalid value for `title`: {}", e),
4769
+ )
4770
+ })?),
4771
+ None => None,
4772
+ },
4773
+ description: match kwargs.get(ruby.to_symbol("description")).filter(|v| !v.is_nil()) {
4774
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4775
+ magnus::Error::new(
4776
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4777
+ format!("invalid value for `description`: {}", e),
4778
+ )
4779
+ })?),
4780
+ None => None,
4781
+ },
4782
+ canonical_url: match kwargs.get(ruby.to_symbol("canonical_url")).filter(|v| !v.is_nil()) {
4783
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4784
+ magnus::Error::new(
4785
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4786
+ format!("invalid value for `canonical_url`: {}", e),
4787
+ )
4788
+ })?),
4789
+ None => None,
4790
+ },
4791
+ keywords: match kwargs.get(ruby.to_symbol("keywords")).filter(|v| !v.is_nil()) {
4792
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4793
+ magnus::Error::new(
4794
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4795
+ format!("invalid value for `keywords`: {}", e),
4796
+ )
4797
+ })?),
4798
+ None => None,
4799
+ },
4800
+ author: match kwargs.get(ruby.to_symbol("author")).filter(|v| !v.is_nil()) {
4801
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4802
+ magnus::Error::new(
4803
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4804
+ format!("invalid value for `author`: {}", e),
4805
+ )
4806
+ })?),
4807
+ None => None,
4808
+ },
4809
+ viewport: match kwargs.get(ruby.to_symbol("viewport")).filter(|v| !v.is_nil()) {
4810
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4811
+ magnus::Error::new(
4812
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4813
+ format!("invalid value for `viewport`: {}", e),
4814
+ )
4815
+ })?),
4816
+ None => None,
4817
+ },
4818
+ theme_color: match kwargs.get(ruby.to_symbol("theme_color")).filter(|v| !v.is_nil()) {
4819
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4820
+ magnus::Error::new(
4821
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4822
+ format!("invalid value for `theme_color`: {}", e),
4823
+ )
4824
+ })?),
4825
+ None => None,
4826
+ },
4827
+ generator: match kwargs.get(ruby.to_symbol("generator")).filter(|v| !v.is_nil()) {
4828
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4829
+ magnus::Error::new(
4830
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4831
+ format!("invalid value for `generator`: {}", e),
4832
+ )
4833
+ })?),
4834
+ None => None,
4835
+ },
4836
+ robots: match kwargs.get(ruby.to_symbol("robots")).filter(|v| !v.is_nil()) {
4837
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4838
+ magnus::Error::new(
4839
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4840
+ format!("invalid value for `robots`: {}", e),
4841
+ )
4842
+ })?),
4843
+ None => None,
4844
+ },
4845
+ html_lang: match kwargs.get(ruby.to_symbol("html_lang")).filter(|v| !v.is_nil()) {
4846
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4847
+ magnus::Error::new(
4848
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4849
+ format!("invalid value for `html_lang`: {}", e),
4850
+ )
4851
+ })?),
4852
+ None => None,
4853
+ },
4854
+ html_dir: match kwargs.get(ruby.to_symbol("html_dir")).filter(|v| !v.is_nil()) {
4855
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4856
+ magnus::Error::new(
4857
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4858
+ format!("invalid value for `html_dir`: {}", e),
4859
+ )
4860
+ })?),
4861
+ None => None,
4862
+ },
4863
+ og_title: match kwargs.get(ruby.to_symbol("og_title")).filter(|v| !v.is_nil()) {
4864
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4865
+ magnus::Error::new(
4866
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4867
+ format!("invalid value for `og_title`: {}", e),
4868
+ )
4869
+ })?),
4870
+ None => None,
4871
+ },
4872
+ og_type: match kwargs.get(ruby.to_symbol("og_type")).filter(|v| !v.is_nil()) {
4873
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4874
+ magnus::Error::new(
4875
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4876
+ format!("invalid value for `og_type`: {}", e),
4877
+ )
4878
+ })?),
4879
+ None => None,
4880
+ },
4881
+ og_image: match kwargs.get(ruby.to_symbol("og_image")).filter(|v| !v.is_nil()) {
4882
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4883
+ magnus::Error::new(
4884
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4885
+ format!("invalid value for `og_image`: {}", e),
4886
+ )
4887
+ })?),
4888
+ None => None,
4889
+ },
4890
+ og_description: match kwargs.get(ruby.to_symbol("og_description")).filter(|v| !v.is_nil()) {
4891
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4892
+ magnus::Error::new(
4893
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4894
+ format!("invalid value for `og_description`: {}", e),
4895
+ )
4896
+ })?),
4897
+ None => None,
4898
+ },
4899
+ og_url: match kwargs.get(ruby.to_symbol("og_url")).filter(|v| !v.is_nil()) {
4900
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4901
+ magnus::Error::new(
4902
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4903
+ format!("invalid value for `og_url`: {}", e),
4904
+ )
4905
+ })?),
4906
+ None => None,
4907
+ },
4908
+ og_site_name: match kwargs.get(ruby.to_symbol("og_site_name")).filter(|v| !v.is_nil()) {
4909
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4910
+ magnus::Error::new(
4911
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4912
+ format!("invalid value for `og_site_name`: {}", e),
4913
+ )
4914
+ })?),
4915
+ None => None,
4916
+ },
4917
+ og_locale: match kwargs.get(ruby.to_symbol("og_locale")).filter(|v| !v.is_nil()) {
4918
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4919
+ magnus::Error::new(
4920
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4921
+ format!("invalid value for `og_locale`: {}", e),
4922
+ )
4923
+ })?),
4924
+ None => None,
4925
+ },
4926
+ og_video: match kwargs.get(ruby.to_symbol("og_video")).filter(|v| !v.is_nil()) {
4927
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4928
+ magnus::Error::new(
4929
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4930
+ format!("invalid value for `og_video`: {}", e),
4931
+ )
4932
+ })?),
4933
+ None => None,
4934
+ },
4935
+ og_audio: match kwargs.get(ruby.to_symbol("og_audio")).filter(|v| !v.is_nil()) {
4936
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4937
+ magnus::Error::new(
4938
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4939
+ format!("invalid value for `og_audio`: {}", e),
4940
+ )
4941
+ })?),
4942
+ None => None,
4943
+ },
4944
+ og_locale_alternates: match kwargs
3703
4945
  .get(ruby.to_symbol("og_locale_alternates"))
3704
- .and_then(|v| <Vec<String>>::try_convert(v).ok()),
3705
- twitter_card: kwargs
3706
- .get(ruby.to_symbol("twitter_card"))
3707
- .and_then(|v| String::try_convert(v).ok()),
3708
- twitter_title: kwargs
3709
- .get(ruby.to_symbol("twitter_title"))
3710
- .and_then(|v| String::try_convert(v).ok()),
3711
- twitter_description: kwargs
4946
+ .filter(|v| !v.is_nil())
4947
+ {
4948
+ Some(v) => Some(<Vec<String>>::try_convert(v).map_err(|e| {
4949
+ magnus::Error::new(
4950
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4951
+ format!("invalid value for `og_locale_alternates`: {}", e),
4952
+ )
4953
+ })?),
4954
+ None => None,
4955
+ },
4956
+ twitter_card: match kwargs.get(ruby.to_symbol("twitter_card")).filter(|v| !v.is_nil()) {
4957
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4958
+ magnus::Error::new(
4959
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4960
+ format!("invalid value for `twitter_card`: {}", e),
4961
+ )
4962
+ })?),
4963
+ None => None,
4964
+ },
4965
+ twitter_title: match kwargs.get(ruby.to_symbol("twitter_title")).filter(|v| !v.is_nil()) {
4966
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4967
+ magnus::Error::new(
4968
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4969
+ format!("invalid value for `twitter_title`: {}", e),
4970
+ )
4971
+ })?),
4972
+ None => None,
4973
+ },
4974
+ twitter_description: match kwargs
3712
4975
  .get(ruby.to_symbol("twitter_description"))
3713
- .and_then(|v| String::try_convert(v).ok()),
3714
- twitter_image: kwargs
3715
- .get(ruby.to_symbol("twitter_image"))
3716
- .and_then(|v| String::try_convert(v).ok()),
3717
- twitter_site: kwargs
3718
- .get(ruby.to_symbol("twitter_site"))
3719
- .and_then(|v| String::try_convert(v).ok()),
3720
- twitter_creator: kwargs
3721
- .get(ruby.to_symbol("twitter_creator"))
3722
- .and_then(|v| String::try_convert(v).ok()),
3723
- dc_title: kwargs
3724
- .get(ruby.to_symbol("dc_title"))
3725
- .and_then(|v| String::try_convert(v).ok()),
3726
- dc_creator: kwargs
3727
- .get(ruby.to_symbol("dc_creator"))
3728
- .and_then(|v| String::try_convert(v).ok()),
3729
- dc_subject: kwargs
3730
- .get(ruby.to_symbol("dc_subject"))
3731
- .and_then(|v| String::try_convert(v).ok()),
3732
- dc_description: kwargs
3733
- .get(ruby.to_symbol("dc_description"))
3734
- .and_then(|v| String::try_convert(v).ok()),
3735
- dc_publisher: kwargs
3736
- .get(ruby.to_symbol("dc_publisher"))
3737
- .and_then(|v| String::try_convert(v).ok()),
3738
- dc_date: kwargs
3739
- .get(ruby.to_symbol("dc_date"))
3740
- .and_then(|v| String::try_convert(v).ok()),
3741
- dc_type: kwargs
3742
- .get(ruby.to_symbol("dc_type"))
3743
- .and_then(|v| String::try_convert(v).ok()),
3744
- dc_format: kwargs
3745
- .get(ruby.to_symbol("dc_format"))
3746
- .and_then(|v| String::try_convert(v).ok()),
3747
- dc_identifier: kwargs
3748
- .get(ruby.to_symbol("dc_identifier"))
3749
- .and_then(|v| String::try_convert(v).ok()),
3750
- dc_language: kwargs
3751
- .get(ruby.to_symbol("dc_language"))
3752
- .and_then(|v| String::try_convert(v).ok()),
3753
- dc_rights: kwargs
3754
- .get(ruby.to_symbol("dc_rights"))
3755
- .and_then(|v| String::try_convert(v).ok()),
3756
- article: kwargs
3757
- .get(ruby.to_symbol("article"))
3758
- .and_then(|v| ArticleMetadata::try_convert(v).ok()),
3759
- hreflangs: kwargs
3760
- .get(ruby.to_symbol("hreflangs"))
3761
- .and_then(|v| <Vec<HreflangEntry>>::try_convert(v).ok()),
3762
- favicons: kwargs
3763
- .get(ruby.to_symbol("favicons"))
3764
- .and_then(|v| <Vec<FaviconInfo>>::try_convert(v).ok()),
3765
- headings: kwargs
3766
- .get(ruby.to_symbol("headings"))
3767
- .and_then(|v| <Vec<HeadingInfo>>::try_convert(v).ok()),
3768
- word_count: kwargs
3769
- .get(ruby.to_symbol("word_count"))
3770
- .and_then(|v| usize::try_convert(v).ok()),
4976
+ .filter(|v| !v.is_nil())
4977
+ {
4978
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4979
+ magnus::Error::new(
4980
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4981
+ format!("invalid value for `twitter_description`: {}", e),
4982
+ )
4983
+ })?),
4984
+ None => None,
4985
+ },
4986
+ twitter_image: match kwargs.get(ruby.to_symbol("twitter_image")).filter(|v| !v.is_nil()) {
4987
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4988
+ magnus::Error::new(
4989
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4990
+ format!("invalid value for `twitter_image`: {}", e),
4991
+ )
4992
+ })?),
4993
+ None => None,
4994
+ },
4995
+ twitter_site: match kwargs.get(ruby.to_symbol("twitter_site")).filter(|v| !v.is_nil()) {
4996
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4997
+ magnus::Error::new(
4998
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4999
+ format!("invalid value for `twitter_site`: {}", e),
5000
+ )
5001
+ })?),
5002
+ None => None,
5003
+ },
5004
+ twitter_creator: match kwargs.get(ruby.to_symbol("twitter_creator")).filter(|v| !v.is_nil()) {
5005
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5006
+ magnus::Error::new(
5007
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5008
+ format!("invalid value for `twitter_creator`: {}", e),
5009
+ )
5010
+ })?),
5011
+ None => None,
5012
+ },
5013
+ dc_title: match kwargs.get(ruby.to_symbol("dc_title")).filter(|v| !v.is_nil()) {
5014
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5015
+ magnus::Error::new(
5016
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5017
+ format!("invalid value for `dc_title`: {}", e),
5018
+ )
5019
+ })?),
5020
+ None => None,
5021
+ },
5022
+ dc_creator: match kwargs.get(ruby.to_symbol("dc_creator")).filter(|v| !v.is_nil()) {
5023
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5024
+ magnus::Error::new(
5025
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5026
+ format!("invalid value for `dc_creator`: {}", e),
5027
+ )
5028
+ })?),
5029
+ None => None,
5030
+ },
5031
+ dc_subject: match kwargs.get(ruby.to_symbol("dc_subject")).filter(|v| !v.is_nil()) {
5032
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5033
+ magnus::Error::new(
5034
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5035
+ format!("invalid value for `dc_subject`: {}", e),
5036
+ )
5037
+ })?),
5038
+ None => None,
5039
+ },
5040
+ dc_description: match kwargs.get(ruby.to_symbol("dc_description")).filter(|v| !v.is_nil()) {
5041
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5042
+ magnus::Error::new(
5043
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5044
+ format!("invalid value for `dc_description`: {}", e),
5045
+ )
5046
+ })?),
5047
+ None => None,
5048
+ },
5049
+ dc_publisher: match kwargs.get(ruby.to_symbol("dc_publisher")).filter(|v| !v.is_nil()) {
5050
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5051
+ magnus::Error::new(
5052
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5053
+ format!("invalid value for `dc_publisher`: {}", e),
5054
+ )
5055
+ })?),
5056
+ None => None,
5057
+ },
5058
+ dc_date: match kwargs.get(ruby.to_symbol("dc_date")).filter(|v| !v.is_nil()) {
5059
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5060
+ magnus::Error::new(
5061
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5062
+ format!("invalid value for `dc_date`: {}", e),
5063
+ )
5064
+ })?),
5065
+ None => None,
5066
+ },
5067
+ dc_type: match kwargs.get(ruby.to_symbol("dc_type")).filter(|v| !v.is_nil()) {
5068
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5069
+ magnus::Error::new(
5070
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5071
+ format!("invalid value for `dc_type`: {}", e),
5072
+ )
5073
+ })?),
5074
+ None => None,
5075
+ },
5076
+ dc_format: match kwargs.get(ruby.to_symbol("dc_format")).filter(|v| !v.is_nil()) {
5077
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5078
+ magnus::Error::new(
5079
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5080
+ format!("invalid value for `dc_format`: {}", e),
5081
+ )
5082
+ })?),
5083
+ None => None,
5084
+ },
5085
+ dc_identifier: match kwargs.get(ruby.to_symbol("dc_identifier")).filter(|v| !v.is_nil()) {
5086
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5087
+ magnus::Error::new(
5088
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5089
+ format!("invalid value for `dc_identifier`: {}", e),
5090
+ )
5091
+ })?),
5092
+ None => None,
5093
+ },
5094
+ dc_language: match kwargs.get(ruby.to_symbol("dc_language")).filter(|v| !v.is_nil()) {
5095
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5096
+ magnus::Error::new(
5097
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5098
+ format!("invalid value for `dc_language`: {}", e),
5099
+ )
5100
+ })?),
5101
+ None => None,
5102
+ },
5103
+ dc_rights: match kwargs.get(ruby.to_symbol("dc_rights")).filter(|v| !v.is_nil()) {
5104
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5105
+ magnus::Error::new(
5106
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5107
+ format!("invalid value for `dc_rights`: {}", e),
5108
+ )
5109
+ })?),
5110
+ None => None,
5111
+ },
5112
+ article: match kwargs.get(ruby.to_symbol("article")).filter(|v| !v.is_nil()) {
5113
+ Some(v) => Some(ArticleMetadata::try_convert(v).map_err(|e| {
5114
+ magnus::Error::new(
5115
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5116
+ format!("invalid value for `article`: {}", e),
5117
+ )
5118
+ })?),
5119
+ None => None,
5120
+ },
5121
+ hreflangs: match kwargs.get(ruby.to_symbol("hreflangs")).filter(|v| !v.is_nil()) {
5122
+ Some(v) => Some(<Vec<HreflangEntry>>::try_convert(v).map_err(|e| {
5123
+ magnus::Error::new(
5124
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5125
+ format!("invalid value for `hreflangs`: {}", e),
5126
+ )
5127
+ })?),
5128
+ None => None,
5129
+ },
5130
+ favicons: match kwargs.get(ruby.to_symbol("favicons")).filter(|v| !v.is_nil()) {
5131
+ Some(v) => Some(<Vec<FaviconInfo>>::try_convert(v).map_err(|e| {
5132
+ magnus::Error::new(
5133
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5134
+ format!("invalid value for `favicons`: {}", e),
5135
+ )
5136
+ })?),
5137
+ None => None,
5138
+ },
5139
+ headings: match kwargs.get(ruby.to_symbol("headings")).filter(|v| !v.is_nil()) {
5140
+ Some(v) => Some(<Vec<HeadingInfo>>::try_convert(v).map_err(|e| {
5141
+ magnus::Error::new(
5142
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5143
+ format!("invalid value for `headings`: {}", e),
5144
+ )
5145
+ })?),
5146
+ None => None,
5147
+ },
5148
+ word_count: match kwargs.get(ruby.to_symbol("word_count")).filter(|v| !v.is_nil()) {
5149
+ Some(v) => Some(usize::try_convert(v).map_err(|e| {
5150
+ magnus::Error::new(
5151
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5152
+ format!("invalid value for `word_count`: {}", e),
5153
+ )
5154
+ })?),
5155
+ None => None,
5156
+ },
3771
5157
  })
3772
5158
  }
3773
5159
 
@@ -3994,16 +5380,33 @@ impl ProxyConfig {
3994
5380
  let (kwargs_opt,) = args.optional;
3995
5381
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
3996
5382
  Ok(Self {
3997
- url: kwargs
3998
- .get(ruby.to_symbol("url"))
3999
- .and_then(|v| String::try_convert(v).ok())
4000
- .unwrap_or_default(),
4001
- username: kwargs
4002
- .get(ruby.to_symbol("username"))
4003
- .and_then(|v| String::try_convert(v).ok()),
4004
- password: kwargs
4005
- .get(ruby.to_symbol("password"))
4006
- .and_then(|v| String::try_convert(v).ok()),
5383
+ url: match kwargs.get(ruby.to_symbol("url")) {
5384
+ Some(v) => String::try_convert(v).map_err(|e| {
5385
+ magnus::Error::new(
5386
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5387
+ format!("invalid value for `url`: {}", e),
5388
+ )
5389
+ })?,
5390
+ None => Default::default(),
5391
+ },
5392
+ username: match kwargs.get(ruby.to_symbol("username")).filter(|v| !v.is_nil()) {
5393
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5394
+ magnus::Error::new(
5395
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5396
+ format!("invalid value for `username`: {}", e),
5397
+ )
5398
+ })?),
5399
+ None => None,
5400
+ },
5401
+ password: match kwargs.get(ruby.to_symbol("password")).filter(|v| !v.is_nil()) {
5402
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5403
+ magnus::Error::new(
5404
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5405
+ format!("invalid value for `password`: {}", e),
5406
+ )
5407
+ })?),
5408
+ None => None,
5409
+ },
4007
5410
  })
4008
5411
  }
4009
5412
 
@@ -4074,27 +5477,69 @@ impl ResponseMeta {
4074
5477
  let (kwargs_opt,) = args.optional;
4075
5478
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
4076
5479
  Ok(Self {
4077
- etag: kwargs
4078
- .get(ruby.to_symbol("etag"))
4079
- .and_then(|v| String::try_convert(v).ok()),
4080
- last_modified: kwargs
4081
- .get(ruby.to_symbol("last_modified"))
4082
- .and_then(|v| String::try_convert(v).ok()),
4083
- cache_control: kwargs
4084
- .get(ruby.to_symbol("cache_control"))
4085
- .and_then(|v| String::try_convert(v).ok()),
4086
- server: kwargs
4087
- .get(ruby.to_symbol("server"))
4088
- .and_then(|v| String::try_convert(v).ok()),
4089
- x_powered_by: kwargs
4090
- .get(ruby.to_symbol("x_powered_by"))
4091
- .and_then(|v| String::try_convert(v).ok()),
4092
- content_language: kwargs
4093
- .get(ruby.to_symbol("content_language"))
4094
- .and_then(|v| String::try_convert(v).ok()),
4095
- content_encoding: kwargs
4096
- .get(ruby.to_symbol("content_encoding"))
4097
- .and_then(|v| String::try_convert(v).ok()),
5480
+ etag: match kwargs.get(ruby.to_symbol("etag")).filter(|v| !v.is_nil()) {
5481
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5482
+ magnus::Error::new(
5483
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5484
+ format!("invalid value for `etag`: {}", e),
5485
+ )
5486
+ })?),
5487
+ None => None,
5488
+ },
5489
+ last_modified: match kwargs.get(ruby.to_symbol("last_modified")).filter(|v| !v.is_nil()) {
5490
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5491
+ magnus::Error::new(
5492
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5493
+ format!("invalid value for `last_modified`: {}", e),
5494
+ )
5495
+ })?),
5496
+ None => None,
5497
+ },
5498
+ cache_control: match kwargs.get(ruby.to_symbol("cache_control")).filter(|v| !v.is_nil()) {
5499
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5500
+ magnus::Error::new(
5501
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5502
+ format!("invalid value for `cache_control`: {}", e),
5503
+ )
5504
+ })?),
5505
+ None => None,
5506
+ },
5507
+ server: match kwargs.get(ruby.to_symbol("server")).filter(|v| !v.is_nil()) {
5508
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5509
+ magnus::Error::new(
5510
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5511
+ format!("invalid value for `server`: {}", e),
5512
+ )
5513
+ })?),
5514
+ None => None,
5515
+ },
5516
+ x_powered_by: match kwargs.get(ruby.to_symbol("x_powered_by")).filter(|v| !v.is_nil()) {
5517
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5518
+ magnus::Error::new(
5519
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5520
+ format!("invalid value for `x_powered_by`: {}", e),
5521
+ )
5522
+ })?),
5523
+ None => None,
5524
+ },
5525
+ content_language: match kwargs.get(ruby.to_symbol("content_language")).filter(|v| !v.is_nil()) {
5526
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5527
+ magnus::Error::new(
5528
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5529
+ format!("invalid value for `content_language`: {}", e),
5530
+ )
5531
+ })?),
5532
+ None => None,
5533
+ },
5534
+ content_encoding: match kwargs.get(ruby.to_symbol("content_encoding")).filter(|v| !v.is_nil()) {
5535
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5536
+ magnus::Error::new(
5537
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5538
+ format!("invalid value for `content_encoding`: {}", e),
5539
+ )
5540
+ })?),
5541
+ None => None,
5542
+ },
4098
5543
  })
4099
5544
  }
4100
5545
 
@@ -4203,112 +5648,270 @@ impl ScrapeResult {
4203
5648
  let (kwargs_opt,) = args.optional;
4204
5649
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
4205
5650
  Ok(Self {
4206
- status_code: kwargs
4207
- .get(ruby.to_symbol("status_code"))
4208
- .and_then(|v| u16::try_convert(v).ok())
4209
- .unwrap_or_default(),
4210
- final_url: kwargs
4211
- .get(ruby.to_symbol("final_url"))
4212
- .and_then(|v| String::try_convert(v).ok())
4213
- .unwrap_or_default(),
4214
- content_type: kwargs
4215
- .get(ruby.to_symbol("content_type"))
4216
- .and_then(|v| String::try_convert(v).ok())
4217
- .unwrap_or_default(),
4218
- html: kwargs
4219
- .get(ruby.to_symbol("html"))
4220
- .and_then(|v| String::try_convert(v).ok())
4221
- .unwrap_or_default(),
4222
- body_size: kwargs
4223
- .get(ruby.to_symbol("body_size"))
4224
- .and_then(|v| usize::try_convert(v).ok())
4225
- .unwrap_or_default(),
4226
- metadata: kwargs
4227
- .get(ruby.to_symbol("metadata"))
4228
- .and_then(|v| PageMetadata::try_convert(v).ok())
4229
- .unwrap_or_default(),
4230
- links: kwargs
4231
- .get(ruby.to_symbol("links"))
4232
- .and_then(|v| <Vec<LinkInfo>>::try_convert(v).ok())
4233
- .unwrap_or_default(),
4234
- images: kwargs
4235
- .get(ruby.to_symbol("images"))
4236
- .and_then(|v| <Vec<ImageInfo>>::try_convert(v).ok())
4237
- .unwrap_or_default(),
4238
- feeds: kwargs
4239
- .get(ruby.to_symbol("feeds"))
4240
- .and_then(|v| <Vec<FeedInfo>>::try_convert(v).ok())
4241
- .unwrap_or_default(),
4242
- json_ld: kwargs
4243
- .get(ruby.to_symbol("json_ld"))
4244
- .and_then(|v| <Vec<JsonLdEntry>>::try_convert(v).ok())
4245
- .unwrap_or_default(),
4246
- is_allowed: kwargs
4247
- .get(ruby.to_symbol("is_allowed"))
4248
- .and_then(|v| bool::try_convert(v).ok())
4249
- .unwrap_or_default(),
4250
- crawl_delay: kwargs
4251
- .get(ruby.to_symbol("crawl_delay"))
4252
- .and_then(|v| u64::try_convert(v).ok()),
4253
- noindex_detected: kwargs
4254
- .get(ruby.to_symbol("noindex_detected"))
4255
- .and_then(|v| bool::try_convert(v).ok())
4256
- .unwrap_or_default(),
4257
- nofollow_detected: kwargs
4258
- .get(ruby.to_symbol("nofollow_detected"))
4259
- .and_then(|v| bool::try_convert(v).ok())
4260
- .unwrap_or_default(),
4261
- x_robots_tag: kwargs
4262
- .get(ruby.to_symbol("x_robots_tag"))
4263
- .and_then(|v| String::try_convert(v).ok()),
4264
- is_pdf: kwargs
4265
- .get(ruby.to_symbol("is_pdf"))
4266
- .and_then(|v| bool::try_convert(v).ok())
4267
- .unwrap_or_default(),
4268
- was_skipped: kwargs
4269
- .get(ruby.to_symbol("was_skipped"))
4270
- .and_then(|v| bool::try_convert(v).ok())
4271
- .unwrap_or_default(),
4272
- detected_charset: kwargs
4273
- .get(ruby.to_symbol("detected_charset"))
4274
- .and_then(|v| String::try_convert(v).ok()),
4275
- auth_header_sent: kwargs
4276
- .get(ruby.to_symbol("auth_header_sent"))
4277
- .and_then(|v| bool::try_convert(v).ok())
4278
- .unwrap_or_default(),
4279
- response_meta: kwargs
4280
- .get(ruby.to_symbol("response_meta"))
4281
- .and_then(|v| ResponseMeta::try_convert(v).ok()),
4282
- assets: kwargs
4283
- .get(ruby.to_symbol("assets"))
4284
- .and_then(|v| <Vec<DownloadedAsset>>::try_convert(v).ok())
4285
- .unwrap_or_default(),
4286
- js_render_hint: kwargs
4287
- .get(ruby.to_symbol("js_render_hint"))
4288
- .and_then(|v| bool::try_convert(v).ok())
4289
- .unwrap_or_default(),
4290
- browser_used: kwargs
4291
- .get(ruby.to_symbol("browser_used"))
4292
- .and_then(|v| bool::try_convert(v).ok())
4293
- .unwrap_or_default(),
4294
- markdown: kwargs
4295
- .get(ruby.to_symbol("markdown"))
4296
- .and_then(|v| MarkdownResult::try_convert(v).ok()),
4297
- extracted_data: kwargs
4298
- .get(ruby.to_symbol("extracted_data"))
4299
- .and_then(|v| String::try_convert(v).ok()),
4300
- extraction_meta: kwargs
4301
- .get(ruby.to_symbol("extraction_meta"))
4302
- .and_then(|v| ExtractionMeta::try_convert(v).ok()),
4303
- screenshot_base64: kwargs
4304
- .get(ruby.to_symbol("screenshot_base64"))
4305
- .and_then(|v| String::try_convert(v).ok()),
4306
- downloaded_document: kwargs
5651
+ status_code: match kwargs.get(ruby.to_symbol("status_code")) {
5652
+ Some(v) => u16::try_convert(v).map_err(|e| {
5653
+ magnus::Error::new(
5654
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5655
+ format!("invalid value for `status_code`: {}", e),
5656
+ )
5657
+ })?,
5658
+ None => Default::default(),
5659
+ },
5660
+ final_url: match kwargs.get(ruby.to_symbol("final_url")) {
5661
+ Some(v) => String::try_convert(v).map_err(|e| {
5662
+ magnus::Error::new(
5663
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5664
+ format!("invalid value for `final_url`: {}", e),
5665
+ )
5666
+ })?,
5667
+ None => Default::default(),
5668
+ },
5669
+ content_type: match kwargs.get(ruby.to_symbol("content_type")) {
5670
+ Some(v) => String::try_convert(v).map_err(|e| {
5671
+ magnus::Error::new(
5672
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5673
+ format!("invalid value for `content_type`: {}", e),
5674
+ )
5675
+ })?,
5676
+ None => Default::default(),
5677
+ },
5678
+ html: match kwargs.get(ruby.to_symbol("html")) {
5679
+ Some(v) => String::try_convert(v).map_err(|e| {
5680
+ magnus::Error::new(
5681
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5682
+ format!("invalid value for `html`: {}", e),
5683
+ )
5684
+ })?,
5685
+ None => Default::default(),
5686
+ },
5687
+ body_size: match kwargs.get(ruby.to_symbol("body_size")) {
5688
+ Some(v) => usize::try_convert(v).map_err(|e| {
5689
+ magnus::Error::new(
5690
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5691
+ format!("invalid value for `body_size`: {}", e),
5692
+ )
5693
+ })?,
5694
+ None => Default::default(),
5695
+ },
5696
+ metadata: match kwargs.get(ruby.to_symbol("metadata")) {
5697
+ Some(v) => PageMetadata::try_convert(v).map_err(|e| {
5698
+ magnus::Error::new(
5699
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5700
+ format!("invalid value for `metadata`: {}", e),
5701
+ )
5702
+ })?,
5703
+ None => Default::default(),
5704
+ },
5705
+ links: match kwargs.get(ruby.to_symbol("links")) {
5706
+ Some(v) => <Vec<LinkInfo>>::try_convert(v).map_err(|e| {
5707
+ magnus::Error::new(
5708
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5709
+ format!("invalid value for `links`: {}", e),
5710
+ )
5711
+ })?,
5712
+ None => Default::default(),
5713
+ },
5714
+ images: match kwargs.get(ruby.to_symbol("images")) {
5715
+ Some(v) => <Vec<ImageInfo>>::try_convert(v).map_err(|e| {
5716
+ magnus::Error::new(
5717
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5718
+ format!("invalid value for `images`: {}", e),
5719
+ )
5720
+ })?,
5721
+ None => Default::default(),
5722
+ },
5723
+ feeds: match kwargs.get(ruby.to_symbol("feeds")) {
5724
+ Some(v) => <Vec<FeedInfo>>::try_convert(v).map_err(|e| {
5725
+ magnus::Error::new(
5726
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5727
+ format!("invalid value for `feeds`: {}", e),
5728
+ )
5729
+ })?,
5730
+ None => Default::default(),
5731
+ },
5732
+ json_ld: match kwargs.get(ruby.to_symbol("json_ld")) {
5733
+ Some(v) => <Vec<JsonLdEntry>>::try_convert(v).map_err(|e| {
5734
+ magnus::Error::new(
5735
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5736
+ format!("invalid value for `json_ld`: {}", e),
5737
+ )
5738
+ })?,
5739
+ None => Default::default(),
5740
+ },
5741
+ is_allowed: match kwargs.get(ruby.to_symbol("is_allowed")) {
5742
+ Some(v) => bool::try_convert(v).map_err(|e| {
5743
+ magnus::Error::new(
5744
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5745
+ format!("invalid value for `is_allowed`: {}", e),
5746
+ )
5747
+ })?,
5748
+ None => Default::default(),
5749
+ },
5750
+ crawl_delay: match kwargs.get(ruby.to_symbol("crawl_delay")).filter(|v| !v.is_nil()) {
5751
+ Some(v) => Some(u64::try_convert(v).map_err(|e| {
5752
+ magnus::Error::new(
5753
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5754
+ format!("invalid value for `crawl_delay`: {}", e),
5755
+ )
5756
+ })?),
5757
+ None => None,
5758
+ },
5759
+ noindex_detected: match kwargs.get(ruby.to_symbol("noindex_detected")) {
5760
+ Some(v) => bool::try_convert(v).map_err(|e| {
5761
+ magnus::Error::new(
5762
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5763
+ format!("invalid value for `noindex_detected`: {}", e),
5764
+ )
5765
+ })?,
5766
+ None => Default::default(),
5767
+ },
5768
+ nofollow_detected: match kwargs.get(ruby.to_symbol("nofollow_detected")) {
5769
+ Some(v) => bool::try_convert(v).map_err(|e| {
5770
+ magnus::Error::new(
5771
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5772
+ format!("invalid value for `nofollow_detected`: {}", e),
5773
+ )
5774
+ })?,
5775
+ None => Default::default(),
5776
+ },
5777
+ x_robots_tag: match kwargs.get(ruby.to_symbol("x_robots_tag")).filter(|v| !v.is_nil()) {
5778
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5779
+ magnus::Error::new(
5780
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5781
+ format!("invalid value for `x_robots_tag`: {}", e),
5782
+ )
5783
+ })?),
5784
+ None => None,
5785
+ },
5786
+ is_pdf: match kwargs.get(ruby.to_symbol("is_pdf")) {
5787
+ Some(v) => bool::try_convert(v).map_err(|e| {
5788
+ magnus::Error::new(
5789
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5790
+ format!("invalid value for `is_pdf`: {}", e),
5791
+ )
5792
+ })?,
5793
+ None => Default::default(),
5794
+ },
5795
+ was_skipped: match kwargs.get(ruby.to_symbol("was_skipped")) {
5796
+ Some(v) => bool::try_convert(v).map_err(|e| {
5797
+ magnus::Error::new(
5798
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5799
+ format!("invalid value for `was_skipped`: {}", e),
5800
+ )
5801
+ })?,
5802
+ None => Default::default(),
5803
+ },
5804
+ detected_charset: match kwargs.get(ruby.to_symbol("detected_charset")).filter(|v| !v.is_nil()) {
5805
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5806
+ magnus::Error::new(
5807
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5808
+ format!("invalid value for `detected_charset`: {}", e),
5809
+ )
5810
+ })?),
5811
+ None => None,
5812
+ },
5813
+ auth_header_sent: match kwargs.get(ruby.to_symbol("auth_header_sent")) {
5814
+ Some(v) => bool::try_convert(v).map_err(|e| {
5815
+ magnus::Error::new(
5816
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5817
+ format!("invalid value for `auth_header_sent`: {}", e),
5818
+ )
5819
+ })?,
5820
+ None => Default::default(),
5821
+ },
5822
+ response_meta: match kwargs.get(ruby.to_symbol("response_meta")).filter(|v| !v.is_nil()) {
5823
+ Some(v) => Some(ResponseMeta::try_convert(v).map_err(|e| {
5824
+ magnus::Error::new(
5825
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5826
+ format!("invalid value for `response_meta`: {}", e),
5827
+ )
5828
+ })?),
5829
+ None => None,
5830
+ },
5831
+ assets: match kwargs.get(ruby.to_symbol("assets")) {
5832
+ Some(v) => <Vec<DownloadedAsset>>::try_convert(v).map_err(|e| {
5833
+ magnus::Error::new(
5834
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5835
+ format!("invalid value for `assets`: {}", e),
5836
+ )
5837
+ })?,
5838
+ None => Default::default(),
5839
+ },
5840
+ js_render_hint: match kwargs.get(ruby.to_symbol("js_render_hint")) {
5841
+ Some(v) => bool::try_convert(v).map_err(|e| {
5842
+ magnus::Error::new(
5843
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5844
+ format!("invalid value for `js_render_hint`: {}", e),
5845
+ )
5846
+ })?,
5847
+ None => Default::default(),
5848
+ },
5849
+ browser_used: match kwargs.get(ruby.to_symbol("browser_used")) {
5850
+ Some(v) => bool::try_convert(v).map_err(|e| {
5851
+ magnus::Error::new(
5852
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5853
+ format!("invalid value for `browser_used`: {}", e),
5854
+ )
5855
+ })?,
5856
+ None => Default::default(),
5857
+ },
5858
+ markdown: match kwargs.get(ruby.to_symbol("markdown")).filter(|v| !v.is_nil()) {
5859
+ Some(v) => Some(MarkdownResult::try_convert(v).map_err(|e| {
5860
+ magnus::Error::new(
5861
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5862
+ format!("invalid value for `markdown`: {}", e),
5863
+ )
5864
+ })?),
5865
+ None => None,
5866
+ },
5867
+ extracted_data: match kwargs.get(ruby.to_symbol("extracted_data")).filter(|v| !v.is_nil()) {
5868
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5869
+ magnus::Error::new(
5870
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5871
+ format!("invalid value for `extracted_data`: {}", e),
5872
+ )
5873
+ })?),
5874
+ None => None,
5875
+ },
5876
+ extraction_meta: match kwargs.get(ruby.to_symbol("extraction_meta")).filter(|v| !v.is_nil()) {
5877
+ Some(v) => Some(ExtractionMeta::try_convert(v).map_err(|e| {
5878
+ magnus::Error::new(
5879
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5880
+ format!("invalid value for `extraction_meta`: {}", e),
5881
+ )
5882
+ })?),
5883
+ None => None,
5884
+ },
5885
+ screenshot_base64: match kwargs.get(ruby.to_symbol("screenshot_base64")).filter(|v| !v.is_nil()) {
5886
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5887
+ magnus::Error::new(
5888
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5889
+ format!("invalid value for `screenshot_base64`: {}", e),
5890
+ )
5891
+ })?),
5892
+ None => None,
5893
+ },
5894
+ downloaded_document: match kwargs
4307
5895
  .get(ruby.to_symbol("downloaded_document"))
4308
- .and_then(|v| DownloadedDocument::try_convert(v).ok()),
4309
- browser: kwargs
4310
- .get(ruby.to_symbol("browser"))
4311
- .and_then(|v| BrowserExtras::try_convert(v).ok()),
5896
+ .filter(|v| !v.is_nil())
5897
+ {
5898
+ Some(v) => Some(DownloadedDocument::try_convert(v).map_err(|e| {
5899
+ magnus::Error::new(
5900
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5901
+ format!("invalid value for `downloaded_document`: {}", e),
5902
+ )
5903
+ })?),
5904
+ None => None,
5905
+ },
5906
+ browser: match kwargs.get(ruby.to_symbol("browser")).filter(|v| !v.is_nil()) {
5907
+ Some(v) => Some(BrowserExtras::try_convert(v).map_err(|e| {
5908
+ magnus::Error::new(
5909
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5910
+ format!("invalid value for `browser`: {}", e),
5911
+ )
5912
+ })?),
5913
+ None => None,
5914
+ },
4312
5915
  })
4313
5916
  }
4314
5917
 
@@ -4480,19 +6083,42 @@ impl SitemapUrl {
4480
6083
  let (kwargs_opt,) = args.optional;
4481
6084
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
4482
6085
  Ok(Self {
4483
- url: kwargs
4484
- .get(ruby.to_symbol("url"))
4485
- .and_then(|v| String::try_convert(v).ok())
4486
- .unwrap_or_default(),
4487
- lastmod: kwargs
4488
- .get(ruby.to_symbol("lastmod"))
4489
- .and_then(|v| String::try_convert(v).ok()),
4490
- changefreq: kwargs
4491
- .get(ruby.to_symbol("changefreq"))
4492
- .and_then(|v| String::try_convert(v).ok()),
4493
- priority: kwargs
4494
- .get(ruby.to_symbol("priority"))
4495
- .and_then(|v| String::try_convert(v).ok()),
6086
+ url: match kwargs.get(ruby.to_symbol("url")) {
6087
+ Some(v) => String::try_convert(v).map_err(|e| {
6088
+ magnus::Error::new(
6089
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
6090
+ format!("invalid value for `url`: {}", e),
6091
+ )
6092
+ })?,
6093
+ None => Default::default(),
6094
+ },
6095
+ lastmod: match kwargs.get(ruby.to_symbol("lastmod")).filter(|v| !v.is_nil()) {
6096
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
6097
+ magnus::Error::new(
6098
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
6099
+ format!("invalid value for `lastmod`: {}", e),
6100
+ )
6101
+ })?),
6102
+ None => None,
6103
+ },
6104
+ changefreq: match kwargs.get(ruby.to_symbol("changefreq")).filter(|v| !v.is_nil()) {
6105
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
6106
+ magnus::Error::new(
6107
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
6108
+ format!("invalid value for `changefreq`: {}", e),
6109
+ )
6110
+ })?),
6111
+ None => None,
6112
+ },
6113
+ priority: match kwargs.get(ruby.to_symbol("priority")).filter(|v| !v.is_nil()) {
6114
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
6115
+ magnus::Error::new(
6116
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
6117
+ format!("invalid value for `priority`: {}", e),
6118
+ )
6119
+ })?),
6120
+ None => None,
6121
+ },
4496
6122
  })
4497
6123
  }
4498
6124
 
@@ -4572,26 +6198,42 @@ impl SsrfPolicy {
4572
6198
  let (kwargs_opt,) = args.optional;
4573
6199
  let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
4574
6200
  Ok(Self {
4575
- deny_private: kwargs
4576
- .get(ruby.to_symbol("deny_private"))
4577
- .and_then(|v| bool::try_convert(v).ok())
4578
- .unwrap_or(true),
4579
- allowlist: kwargs
4580
- .get(ruby.to_symbol("allowlist"))
4581
- .and_then(|v| <Vec<HostMatcher>>::try_convert(v).ok())
4582
- .unwrap_or_default(),
4583
- max_redirects: kwargs
4584
- .get(ruby.to_symbol("max_redirects"))
4585
- .and_then(|v| u8::try_convert(v).ok())
4586
- .unwrap_or(5),
4587
- scheme_allowlist: kwargs
4588
- .get(ruby.to_symbol("scheme_allowlist"))
4589
- .and_then(|v| <Vec<String>>::try_convert(v).ok())
4590
- .unwrap_or(
4591
- serde_json::from_str::<crawlberg::SsrfPolicy>(r#"{}"#)
4592
- .expect("alef-generated default JSON for `SsrfPolicy` failed to deserialize")
4593
- .scheme_allowlist,
4594
- ),
6201
+ deny_private: match kwargs.get(ruby.to_symbol("deny_private")) {
6202
+ Some(v) => bool::try_convert(v).map_err(|e| {
6203
+ magnus::Error::new(
6204
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
6205
+ format!("invalid value for `deny_private`: {}", e),
6206
+ )
6207
+ })?,
6208
+ None => true,
6209
+ },
6210
+ allowlist: match kwargs.get(ruby.to_symbol("allowlist")) {
6211
+ Some(v) => <Vec<HostMatcher>>::try_convert(v).map_err(|e| {
6212
+ magnus::Error::new(
6213
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
6214
+ format!("invalid value for `allowlist`: {}", e),
6215
+ )
6216
+ })?,
6217
+ None => Default::default(),
6218
+ },
6219
+ max_redirects: match kwargs.get(ruby.to_symbol("max_redirects")) {
6220
+ Some(v) => u8::try_convert(v).map_err(|e| {
6221
+ magnus::Error::new(
6222
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
6223
+ format!("invalid value for `max_redirects`: {}", e),
6224
+ )
6225
+ })?,
6226
+ None => 5,
6227
+ },
6228
+ scheme_allowlist: match kwargs.get(ruby.to_symbol("scheme_allowlist")) {
6229
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
6230
+ magnus::Error::new(
6231
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
6232
+ format!("invalid value for `scheme_allowlist`: {}", e),
6233
+ )
6234
+ })?,
6235
+ None => vec!["http".to_string(), "https".to_string()],
6236
+ },
4595
6237
  })
4596
6238
  }
4597
6239
 
@@ -5410,110 +7052,86 @@ unsafe impl IntoValueFromNative for ScrollDirection {}
5410
7052
  unsafe impl TryConvertOwned for ScrollDirection {}
5411
7053
 
5412
7054
  fn batch_crawl(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<BatchCrawlResults, Error> {
5413
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5414
- magnus::Error::new(
5415
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5416
- e.to_string(),
5417
- )
5418
- })?;
5419
- let result = rt
5420
- .block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await })
5421
- .map_err(|e| {
5422
- magnus::Error::new(
5423
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5424
- e.to_string(),
5425
- )
5426
- })?;
7055
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7056
+ let rt = tokio::runtime::Builder::new_current_thread()
7057
+ .enable_all()
7058
+ .build()
7059
+ .map_err(|e| e.to_string())?;
7060
+ rt.block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await })
7061
+ .map_err(|e| e.to_string())
7062
+ });
7063
+ let result = async_result
7064
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5427
7065
  Ok(result.into())
5428
7066
  }
5429
7067
 
5430
7068
  fn batch_crawl_async(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<BatchCrawlResults, Error> {
5431
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5432
- magnus::Error::new(
5433
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5434
- e.to_string(),
5435
- )
5436
- })?;
5437
- let result = rt
5438
- .block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await })
5439
- .map_err(|e| {
5440
- magnus::Error::new(
5441
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5442
- e.to_string(),
5443
- )
5444
- })?;
7069
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7070
+ let rt = tokio::runtime::Builder::new_current_thread()
7071
+ .enable_all()
7072
+ .build()
7073
+ .map_err(|e| e.to_string())?;
7074
+ rt.block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await })
7075
+ .map_err(|e| e.to_string())
7076
+ });
7077
+ let result = async_result
7078
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5445
7079
  Ok(result.into())
5446
7080
  }
5447
7081
 
5448
7082
  fn batch_scrape(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<BatchScrapeResults, Error> {
5449
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5450
- magnus::Error::new(
5451
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5452
- e.to_string(),
5453
- )
5454
- })?;
5455
- let result = rt
5456
- .block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await })
5457
- .map_err(|e| {
5458
- magnus::Error::new(
5459
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5460
- e.to_string(),
5461
- )
5462
- })?;
7083
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7084
+ let rt = tokio::runtime::Builder::new_current_thread()
7085
+ .enable_all()
7086
+ .build()
7087
+ .map_err(|e| e.to_string())?;
7088
+ rt.block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await })
7089
+ .map_err(|e| e.to_string())
7090
+ });
7091
+ let result = async_result
7092
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5463
7093
  Ok(result.into())
5464
7094
  }
5465
7095
 
5466
7096
  fn batch_scrape_async(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<BatchScrapeResults, Error> {
5467
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5468
- magnus::Error::new(
5469
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5470
- e.to_string(),
5471
- )
5472
- })?;
5473
- let result = rt
5474
- .block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await })
5475
- .map_err(|e| {
5476
- magnus::Error::new(
5477
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5478
- e.to_string(),
5479
- )
5480
- })?;
7097
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7098
+ let rt = tokio::runtime::Builder::new_current_thread()
7099
+ .enable_all()
7100
+ .build()
7101
+ .map_err(|e| e.to_string())?;
7102
+ rt.block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await })
7103
+ .map_err(|e| e.to_string())
7104
+ });
7105
+ let result = async_result
7106
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5481
7107
  Ok(result.into())
5482
7108
  }
5483
7109
 
5484
7110
  fn crawl(engine: CrawlEngineHandle, url: String) -> Result<CrawlResult, Error> {
5485
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5486
- magnus::Error::new(
5487
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5488
- e.to_string(),
5489
- )
5490
- })?;
5491
- let result = rt
5492
- .block_on(async { crawlberg::crawl(&engine.inner, &url).await })
5493
- .map_err(|e| {
5494
- magnus::Error::new(
5495
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5496
- e.to_string(),
5497
- )
5498
- })?;
7111
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7112
+ let rt = tokio::runtime::Builder::new_current_thread()
7113
+ .enable_all()
7114
+ .build()
7115
+ .map_err(|e| e.to_string())?;
7116
+ rt.block_on(async { crawlberg::crawl(&engine.inner, &url).await })
7117
+ .map_err(|e| e.to_string())
7118
+ });
7119
+ let result = async_result
7120
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5499
7121
  Ok(result.into())
5500
7122
  }
5501
7123
 
5502
7124
  fn crawl_async(engine: CrawlEngineHandle, url: String) -> Result<CrawlResult, Error> {
5503
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5504
- magnus::Error::new(
5505
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5506
- e.to_string(),
5507
- )
5508
- })?;
5509
- let result = rt
5510
- .block_on(async { crawlberg::crawl(&engine.inner, &url).await })
5511
- .map_err(|e| {
5512
- magnus::Error::new(
5513
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5514
- e.to_string(),
5515
- )
5516
- })?;
7125
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7126
+ let rt = tokio::runtime::Builder::new_current_thread()
7127
+ .enable_all()
7128
+ .build()
7129
+ .map_err(|e| e.to_string())?;
7130
+ rt.block_on(async { crawlberg::crawl(&engine.inner, &url).await })
7131
+ .map_err(|e| e.to_string())
7132
+ });
7133
+ let result = async_result
7134
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5517
7135
  Ok(result.into())
5518
7136
  }
5519
7137
 
@@ -5547,20 +7165,16 @@ fn generate_citations(markdown: String) -> CitationResult {
5547
7165
 
5548
7166
  fn interact(engine: CrawlEngineHandle, url: String, actions: Vec<PageAction>) -> Result<InteractionResult, Error> {
5549
7167
  let actions_core: Vec<crawlberg::PageAction> = actions.into_iter().map(Into::into).collect();
5550
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5551
- magnus::Error::new(
5552
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5553
- e.to_string(),
5554
- )
5555
- })?;
5556
- let result = rt
5557
- .block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await })
5558
- .map_err(|e| {
5559
- magnus::Error::new(
5560
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5561
- e.to_string(),
5562
- )
5563
- })?;
7168
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7169
+ let rt = tokio::runtime::Builder::new_current_thread()
7170
+ .enable_all()
7171
+ .build()
7172
+ .map_err(|e| e.to_string())?;
7173
+ rt.block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await })
7174
+ .map_err(|e| e.to_string())
7175
+ });
7176
+ let result = async_result
7177
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5564
7178
  Ok(result.into())
5565
7179
  }
5566
7180
 
@@ -5570,92 +7184,72 @@ fn interact_async(
5570
7184
  actions: Vec<PageAction>,
5571
7185
  ) -> Result<InteractionResult, Error> {
5572
7186
  let actions_core: Vec<crawlberg::PageAction> = actions.into_iter().map(Into::into).collect();
5573
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5574
- magnus::Error::new(
5575
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5576
- e.to_string(),
5577
- )
5578
- })?;
5579
- let result = rt
5580
- .block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await })
5581
- .map_err(|e| {
5582
- magnus::Error::new(
5583
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5584
- e.to_string(),
5585
- )
5586
- })?;
7187
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7188
+ let rt = tokio::runtime::Builder::new_current_thread()
7189
+ .enable_all()
7190
+ .build()
7191
+ .map_err(|e| e.to_string())?;
7192
+ rt.block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await })
7193
+ .map_err(|e| e.to_string())
7194
+ });
7195
+ let result = async_result
7196
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5587
7197
  Ok(result.into())
5588
7198
  }
5589
7199
 
5590
7200
  fn map_urls(engine: CrawlEngineHandle, url: String) -> Result<MapResult, Error> {
5591
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5592
- magnus::Error::new(
5593
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5594
- e.to_string(),
5595
- )
5596
- })?;
5597
- let result = rt
5598
- .block_on(async { crawlberg::map_urls(&engine.inner, &url).await })
5599
- .map_err(|e| {
5600
- magnus::Error::new(
5601
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5602
- e.to_string(),
5603
- )
5604
- })?;
7201
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7202
+ let rt = tokio::runtime::Builder::new_current_thread()
7203
+ .enable_all()
7204
+ .build()
7205
+ .map_err(|e| e.to_string())?;
7206
+ rt.block_on(async { crawlberg::map_urls(&engine.inner, &url).await })
7207
+ .map_err(|e| e.to_string())
7208
+ });
7209
+ let result = async_result
7210
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5605
7211
  Ok(result.into())
5606
7212
  }
5607
7213
 
5608
7214
  fn map_urls_async(engine: CrawlEngineHandle, url: String) -> Result<MapResult, Error> {
5609
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5610
- magnus::Error::new(
5611
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5612
- e.to_string(),
5613
- )
5614
- })?;
5615
- let result = rt
5616
- .block_on(async { crawlberg::map_urls(&engine.inner, &url).await })
5617
- .map_err(|e| {
5618
- magnus::Error::new(
5619
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5620
- e.to_string(),
5621
- )
5622
- })?;
7215
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7216
+ let rt = tokio::runtime::Builder::new_current_thread()
7217
+ .enable_all()
7218
+ .build()
7219
+ .map_err(|e| e.to_string())?;
7220
+ rt.block_on(async { crawlberg::map_urls(&engine.inner, &url).await })
7221
+ .map_err(|e| e.to_string())
7222
+ });
7223
+ let result = async_result
7224
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5623
7225
  Ok(result.into())
5624
7226
  }
5625
7227
 
5626
7228
  fn scrape(engine: CrawlEngineHandle, url: String) -> Result<ScrapeResult, Error> {
5627
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5628
- magnus::Error::new(
5629
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5630
- e.to_string(),
5631
- )
5632
- })?;
5633
- let result = rt
5634
- .block_on(async { crawlberg::scrape(&engine.inner, &url).await })
5635
- .map_err(|e| {
5636
- magnus::Error::new(
5637
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5638
- e.to_string(),
5639
- )
5640
- })?;
7229
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7230
+ let rt = tokio::runtime::Builder::new_current_thread()
7231
+ .enable_all()
7232
+ .build()
7233
+ .map_err(|e| e.to_string())?;
7234
+ rt.block_on(async { crawlberg::scrape(&engine.inner, &url).await })
7235
+ .map_err(|e| e.to_string())
7236
+ });
7237
+ let result = async_result
7238
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5641
7239
  Ok(result.into())
5642
7240
  }
5643
7241
 
5644
7242
  fn scrape_async(engine: CrawlEngineHandle, url: String) -> Result<ScrapeResult, Error> {
5645
- let rt = tokio::runtime::Runtime::new().map_err(|e| {
5646
- magnus::Error::new(
5647
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5648
- e.to_string(),
5649
- )
5650
- })?;
5651
- let result = rt
5652
- .block_on(async { crawlberg::scrape(&engine.inner, &url).await })
5653
- .map_err(|e| {
5654
- magnus::Error::new(
5655
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
5656
- e.to_string(),
5657
- )
5658
- })?;
7243
+ let async_result = alef_magnus_run_without_gvl(move || -> Result<_, String> {
7244
+ let rt = tokio::runtime::Builder::new_current_thread()
7245
+ .enable_all()
7246
+ .build()
7247
+ .map_err(|e| e.to_string())?;
7248
+ rt.block_on(async { crawlberg::scrape(&engine.inner, &url).await })
7249
+ .map_err(|e| e.to_string())
7250
+ });
7251
+ let result = async_result
7252
+ .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
5659
7253
  Ok(result.into())
5660
7254
  }
5661
7255
 
@@ -7020,6 +8614,7 @@ impl From<crawlberg::ContentFilterKind> for ContentFilterKind {
7020
8614
  }
7021
8615
  }
7022
8616
 
8617
+ #[cfg(not(target_arch = "wasm32"))]
7023
8618
  impl From<crawlberg::CrawlEvent> for CrawlEvent {
7024
8619
  fn from(val: crawlberg::CrawlEvent) -> Self {
7025
8620
  match val {
@@ -7474,8 +9069,10 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
7474
9069
 
7475
9070
  let class = module.define_class("BatchCrawlStreamRequest", ruby.class_object())?;
7476
9071
 
9072
+ #[cfg(not(target_arch = "wasm32"))]
7477
9073
  class.define_singleton_method("new", function!(BatchCrawlStreamRequest::new, -1))?;
7478
9074
 
9075
+ #[cfg(not(target_arch = "wasm32"))]
7479
9076
  class.define_method("urls", method!(BatchCrawlStreamRequest::urls, 0))?;
7480
9077
 
7481
9078
  let class = module.define_class("BatchScrapeResult", ruby.class_object())?;
@@ -7790,8 +9387,10 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
7790
9387
 
7791
9388
  let class = module.define_class("CrawlStreamRequest", ruby.class_object())?;
7792
9389
 
9390
+ #[cfg(not(target_arch = "wasm32"))]
7793
9391
  class.define_singleton_method("new", function!(CrawlStreamRequest::new, -1))?;
7794
9392
 
9393
+ #[cfg(not(target_arch = "wasm32"))]
7795
9394
  class.define_method("url", method!(CrawlStreamRequest::url, 0))?;
7796
9395
 
7797
9396
  let class = module.define_class("DownloadedAsset", ruby.class_object())?;