xberg 1.2.8 → 1.3.0

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:f1a359a24f246b68ebe2717a124008b9358925ba194cc8cb713eb90df7dc417d
2
+ // alef:hash:7b7e0e3e79a8cf968d66bcaa7adae77d99bdb0dc86ad64a75c1e785c57a13371
3
3
  // Re-generate with: alef generate
4
4
  #![allow(dead_code, unused_imports, unused_variables)]
5
5
  #![allow(
@@ -1134,6 +1134,8 @@ pub struct BrowserConfig {
1134
1134
  endpoint: Option<String>,
1135
1135
  #[serde(default = "default_timeout")]
1136
1136
  timeout: u64,
1137
+ overall_timeout: u64,
1138
+ shutdown_timeout: u64,
1137
1139
  wait: BrowserWait,
1138
1140
  wait_selector: Option<String>,
1139
1141
  extra_wait: Option<u64>,
@@ -1230,6 +1232,24 @@ impl BrowserConfig {
1230
1232
  })?,
1231
1233
  None => 30000,
1232
1234
  },
1235
+ overall_timeout: match kwargs.get(ruby.to_symbol("overall_timeout")) {
1236
+ Some(v) => u64::try_convert(v).map_err(|e| {
1237
+ magnus::Error::new(
1238
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1239
+ format!("invalid value for `overall_timeout`: {}", e),
1240
+ )
1241
+ })?,
1242
+ None => 60000,
1243
+ },
1244
+ shutdown_timeout: match kwargs.get(ruby.to_symbol("shutdown_timeout")) {
1245
+ Some(v) => u64::try_convert(v).map_err(|e| {
1246
+ magnus::Error::new(
1247
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1248
+ format!("invalid value for `shutdown_timeout`: {}", e),
1249
+ )
1250
+ })?,
1251
+ None => 5000,
1252
+ },
1233
1253
  wait: match kwargs.get(ruby.to_symbol("wait")) {
1234
1254
  Some(v) => BrowserWait::try_convert(v).map_err(|e| {
1235
1255
  magnus::Error::new(
@@ -1330,6 +1350,14 @@ impl BrowserConfig {
1330
1350
  self.timeout.clone()
1331
1351
  }
1332
1352
 
1353
+ fn overall_timeout(&self) -> u64 {
1354
+ self.overall_timeout.clone()
1355
+ }
1356
+
1357
+ fn shutdown_timeout(&self) -> u64 {
1358
+ self.shutdown_timeout.clone()
1359
+ }
1360
+
1333
1361
  fn wait(&self) -> BrowserWait {
1334
1362
  self.wait.clone()
1335
1363
  }
@@ -3582,6 +3610,7 @@ pub struct ContentConfig {
3582
3610
  wrap: bool,
3583
3611
  wrap_width: usize,
3584
3612
  include_document_structure: bool,
3613
+ extract_metadata: bool,
3585
3614
  }
3586
3615
 
3587
3616
  unsafe impl IntoValueFromNative for ContentConfig {}
@@ -3741,6 +3770,15 @@ impl ContentConfig {
3741
3770
  })?,
3742
3771
  None => true,
3743
3772
  },
3773
+ extract_metadata: match kwargs.get(ruby.to_symbol("extract_metadata")) {
3774
+ Some(v) => bool::try_convert(v).map_err(|e| {
3775
+ magnus::Error::new(
3776
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3777
+ format!("invalid value for `extract_metadata`: {}", e),
3778
+ )
3779
+ })?,
3780
+ None => true,
3781
+ },
3744
3782
  })
3745
3783
  }
3746
3784
 
@@ -3791,6 +3829,10 @@ impl ContentConfig {
3791
3829
  fn include_document_structure(&self) -> bool {
3792
3830
  self.include_document_structure
3793
3831
  }
3832
+
3833
+ fn extract_metadata(&self) -> bool {
3834
+ self.extract_metadata
3835
+ }
3794
3836
  }
3795
3837
 
3796
3838
  #[derive(Clone, Debug, serde::Serialize)]
@@ -4041,6 +4083,7 @@ pub struct ConversionOptions {
4041
4083
  max_depth: Option<usize>,
4042
4084
  exclude_selectors: Vec<String>,
4043
4085
  tier_strategy: TierStrategy,
4086
+ base_url: Option<String>,
4044
4087
  }
4045
4088
 
4046
4089
  unsafe impl IntoValueFromNative for ConversionOptions {}
@@ -4471,6 +4514,15 @@ impl ConversionOptions {
4471
4514
  })?,
4472
4515
  None => TierStrategy::Auto,
4473
4516
  },
4517
+ base_url: match kwargs.get(ruby.to_symbol("base_url")).filter(|v| !v.is_nil()) {
4518
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4519
+ magnus::Error::new(
4520
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4521
+ format!("invalid value for `base_url`: {}", e),
4522
+ )
4523
+ })?),
4524
+ None => None,
4525
+ },
4474
4526
  })
4475
4527
  }
4476
4528
 
@@ -4645,6 +4697,10 @@ impl ConversionOptions {
4645
4697
  fn tier_strategy(&self) -> TierStrategy {
4646
4698
  self.tier_strategy.clone()
4647
4699
  }
4700
+
4701
+ fn base_url(&self) -> Option<String> {
4702
+ self.base_url.clone()
4703
+ }
4648
4704
  }
4649
4705
 
4650
4706
  #[cfg(feature = "office")]
@@ -4933,6 +4989,10 @@ pub struct CrawlConfig {
4933
4989
  allow_subdomains: bool,
4934
4990
  include_paths: Vec<String>,
4935
4991
  exclude_paths: Vec<String>,
4992
+ path_patterns_match_query: bool,
4993
+ dedup_include_query: bool,
4994
+ strip_tracking_params: bool,
4995
+ tracking_params: Vec<String>,
4936
4996
  custom_headers: HashMap<String, String>,
4937
4997
  #[serde(default = "default_timeout")]
4938
4998
  request_timeout: u64,
@@ -4940,6 +5000,9 @@ pub struct CrawlConfig {
4940
5000
  max_redirects: usize,
4941
5001
  retry_count: usize,
4942
5002
  retry_codes: Vec<u16>,
5003
+ retry_initial_delay_ms: u64,
5004
+ retry_max_delay_ms: u64,
5005
+ rate_limit_jitter_ratio: f64,
4943
5006
  cookies_enabled: bool,
4944
5007
  auth: Option<AuthConfig>,
4945
5008
  max_body_size: Option<usize>,
@@ -5144,6 +5207,47 @@ impl CrawlConfig {
5144
5207
  })?,
5145
5208
  None => Default::default(),
5146
5209
  },
5210
+ path_patterns_match_query: match kwargs.get(ruby.to_symbol("path_patterns_match_query")) {
5211
+ Some(v) => bool::try_convert(v).map_err(|e| {
5212
+ magnus::Error::new(
5213
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5214
+ format!("invalid value for `path_patterns_match_query`: {}", e),
5215
+ )
5216
+ })?,
5217
+ None => false,
5218
+ },
5219
+ dedup_include_query: match kwargs.get(ruby.to_symbol("dedup_include_query")) {
5220
+ Some(v) => bool::try_convert(v).map_err(|e| {
5221
+ magnus::Error::new(
5222
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5223
+ format!("invalid value for `dedup_include_query`: {}", e),
5224
+ )
5225
+ })?,
5226
+ None => false,
5227
+ },
5228
+ strip_tracking_params: match kwargs.get(ruby.to_symbol("strip_tracking_params")) {
5229
+ Some(v) => bool::try_convert(v).map_err(|e| {
5230
+ magnus::Error::new(
5231
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5232
+ format!("invalid value for `strip_tracking_params`: {}", e),
5233
+ )
5234
+ })?,
5235
+ None => false,
5236
+ },
5237
+ tracking_params: match kwargs.get(ruby.to_symbol("tracking_params")) {
5238
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
5239
+ magnus::Error::new(
5240
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5241
+ format!("invalid value for `tracking_params`: {}", e),
5242
+ )
5243
+ })?,
5244
+ None => vec![
5245
+ "utm_*".to_string(),
5246
+ "fbclid".to_string(),
5247
+ "gclid".to_string(),
5248
+ "ref".to_string(),
5249
+ ],
5250
+ },
5147
5251
  custom_headers: match kwargs.get(ruby.to_symbol("custom_headers")) {
5148
5252
  Some(v) => <HashMap<String, String>>::try_convert(v).map_err(|e| {
5149
5253
  magnus::Error::new(
@@ -5198,6 +5302,33 @@ impl CrawlConfig {
5198
5302
  })?,
5199
5303
  None => Default::default(),
5200
5304
  },
5305
+ retry_initial_delay_ms: match kwargs.get(ruby.to_symbol("retry_initial_delay_ms")) {
5306
+ Some(v) => u64::try_convert(v).map_err(|e| {
5307
+ magnus::Error::new(
5308
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5309
+ format!("invalid value for `retry_initial_delay_ms`: {}", e),
5310
+ )
5311
+ })?,
5312
+ None => 100,
5313
+ },
5314
+ retry_max_delay_ms: match kwargs.get(ruby.to_symbol("retry_max_delay_ms")) {
5315
+ Some(v) => u64::try_convert(v).map_err(|e| {
5316
+ magnus::Error::new(
5317
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5318
+ format!("invalid value for `retry_max_delay_ms`: {}", e),
5319
+ )
5320
+ })?,
5321
+ None => 60000,
5322
+ },
5323
+ rate_limit_jitter_ratio: match kwargs.get(ruby.to_symbol("rate_limit_jitter_ratio")) {
5324
+ Some(v) => f64::try_convert(v).map_err(|e| {
5325
+ magnus::Error::new(
5326
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5327
+ format!("invalid value for `rate_limit_jitter_ratio`: {}", e),
5328
+ )
5329
+ })?,
5330
+ None => 0.0,
5331
+ },
5201
5332
  cookies_enabled: match kwargs.get(ruby.to_symbol("cookies_enabled")) {
5202
5333
  Some(v) => bool::try_convert(v).map_err(|e| {
5203
5334
  magnus::Error::new(
@@ -5504,6 +5635,22 @@ impl CrawlConfig {
5504
5635
  self.exclude_paths.clone()
5505
5636
  }
5506
5637
 
5638
+ fn path_patterns_match_query(&self) -> bool {
5639
+ self.path_patterns_match_query
5640
+ }
5641
+
5642
+ fn dedup_include_query(&self) -> bool {
5643
+ self.dedup_include_query
5644
+ }
5645
+
5646
+ fn strip_tracking_params(&self) -> bool {
5647
+ self.strip_tracking_params
5648
+ }
5649
+
5650
+ fn tracking_params(&self) -> Vec<String> {
5651
+ self.tracking_params.clone()
5652
+ }
5653
+
5507
5654
  fn custom_headers(&self) -> HashMap<String, String> {
5508
5655
  self.custom_headers.clone()
5509
5656
  }
@@ -5528,6 +5675,18 @@ impl CrawlConfig {
5528
5675
  self.retry_codes.clone()
5529
5676
  }
5530
5677
 
5678
+ fn retry_initial_delay_ms(&self) -> u64 {
5679
+ self.retry_initial_delay_ms
5680
+ }
5681
+
5682
+ fn retry_max_delay_ms(&self) -> u64 {
5683
+ self.retry_max_delay_ms
5684
+ }
5685
+
5686
+ fn rate_limit_jitter_ratio(&self) -> f64 {
5687
+ self.rate_limit_jitter_ratio
5688
+ }
5689
+
5531
5690
  fn cookies_enabled(&self) -> bool {
5532
5691
  self.cookies_enabled
5533
5692
  }
@@ -11754,6 +11913,9 @@ pub struct ExtractionConfig {
11754
11913
  ocr_strategy: OcrStrategy,
11755
11914
  force_ocr_pages: Option<Vec<u32>>,
11756
11915
  disable_ocr: bool,
11916
+ ocr_near_empty_fallback: Option<bool>,
11917
+ ocr_scanned_page_quality_gate: Option<bool>,
11918
+ ocr_embedded_images: Option<bool>,
11757
11919
  chunking: Option<ChunkingConfig>,
11758
11920
  content_filter: Option<ContentFilterConfig>,
11759
11921
  images: Option<ImageExtractionConfig>,
@@ -11920,6 +12082,42 @@ impl ExtractionConfig {
11920
12082
  })?,
11921
12083
  None => false,
11922
12084
  },
12085
+ ocr_near_empty_fallback: match kwargs
12086
+ .get(ruby.to_symbol("ocr_near_empty_fallback"))
12087
+ .filter(|v| !v.is_nil())
12088
+ {
12089
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
12090
+ magnus::Error::new(
12091
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
12092
+ format!("invalid value for `ocr_near_empty_fallback`: {}", e),
12093
+ )
12094
+ })?),
12095
+ None => None,
12096
+ },
12097
+ ocr_scanned_page_quality_gate: match kwargs
12098
+ .get(ruby.to_symbol("ocr_scanned_page_quality_gate"))
12099
+ .filter(|v| !v.is_nil())
12100
+ {
12101
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
12102
+ magnus::Error::new(
12103
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
12104
+ format!("invalid value for `ocr_scanned_page_quality_gate`: {}", e),
12105
+ )
12106
+ })?),
12107
+ None => None,
12108
+ },
12109
+ ocr_embedded_images: match kwargs
12110
+ .get(ruby.to_symbol("ocr_embedded_images"))
12111
+ .filter(|v| !v.is_nil())
12112
+ {
12113
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
12114
+ magnus::Error::new(
12115
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
12116
+ format!("invalid value for `ocr_embedded_images`: {}", e),
12117
+ )
12118
+ })?),
12119
+ None => None,
12120
+ },
11923
12121
  chunking: match kwargs.get(ruby.to_symbol("chunking")).filter(|v| !v.is_nil()) {
11924
12122
  Some(v) => Some(ChunkingConfig::try_convert(v).map_err(|e| {
11925
12123
  magnus::Error::new(
@@ -12376,6 +12574,18 @@ impl ExtractionConfig {
12376
12574
  self.disable_ocr
12377
12575
  }
12378
12576
 
12577
+ fn ocr_near_empty_fallback(&self) -> Option<bool> {
12578
+ self.ocr_near_empty_fallback
12579
+ }
12580
+
12581
+ fn ocr_scanned_page_quality_gate(&self) -> Option<bool> {
12582
+ self.ocr_scanned_page_quality_gate
12583
+ }
12584
+
12585
+ fn ocr_embedded_images(&self) -> Option<bool> {
12586
+ self.ocr_embedded_images
12587
+ }
12588
+
12379
12589
  fn chunking(&self) -> Option<ChunkingConfig> {
12380
12590
  self.chunking.clone()
12381
12591
  }
@@ -12578,6 +12788,12 @@ impl ExtractionConfig {
12578
12788
 
12579
12789
  disable_ocr: self.disable_ocr,
12580
12790
 
12791
+ ocr_near_empty_fallback: self.ocr_near_empty_fallback,
12792
+
12793
+ ocr_scanned_page_quality_gate: self.ocr_scanned_page_quality_gate,
12794
+
12795
+ ocr_embedded_images: self.ocr_embedded_images,
12796
+
12581
12797
  chunking: self.chunking.clone().map(Into::into),
12582
12798
 
12583
12799
  content_filter: self.content_filter.clone().map(Into::into),
@@ -12682,6 +12898,12 @@ impl ExtractionConfig {
12682
12898
 
12683
12899
  disable_ocr: self.disable_ocr,
12684
12900
 
12901
+ ocr_near_empty_fallback: self.ocr_near_empty_fallback,
12902
+
12903
+ ocr_scanned_page_quality_gate: self.ocr_scanned_page_quality_gate,
12904
+
12905
+ ocr_embedded_images: self.ocr_embedded_images,
12906
+
12685
12907
  chunking: self.chunking.clone().map(Into::into),
12686
12908
 
12687
12909
  content_filter: self.content_filter.clone().map(Into::into),
@@ -12780,6 +13002,12 @@ impl ExtractionConfig {
12780
13002
 
12781
13003
  disable_ocr: self.disable_ocr,
12782
13004
 
13005
+ ocr_near_empty_fallback: self.ocr_near_empty_fallback,
13006
+
13007
+ ocr_scanned_page_quality_gate: self.ocr_scanned_page_quality_gate,
13008
+
13009
+ ocr_embedded_images: self.ocr_embedded_images,
13010
+
12783
13011
  chunking: self.chunking.clone().map(Into::into),
12784
13012
 
12785
13013
  content_filter: self.content_filter.clone().map(Into::into),
@@ -12878,6 +13106,12 @@ impl ExtractionConfig {
12878
13106
 
12879
13107
  disable_ocr: self.disable_ocr,
12880
13108
 
13109
+ ocr_near_empty_fallback: self.ocr_near_empty_fallback,
13110
+
13111
+ ocr_scanned_page_quality_gate: self.ocr_scanned_page_quality_gate,
13112
+
13113
+ ocr_embedded_images: self.ocr_embedded_images,
13114
+
12881
13115
  chunking: self.chunking.clone().map(Into::into),
12882
13116
 
12883
13117
  content_filter: self.content_filter.clone().map(Into::into),
@@ -12976,6 +13210,12 @@ impl ExtractionConfig {
12976
13210
 
12977
13211
  disable_ocr: self.disable_ocr,
12978
13212
 
13213
+ ocr_near_empty_fallback: self.ocr_near_empty_fallback,
13214
+
13215
+ ocr_scanned_page_quality_gate: self.ocr_scanned_page_quality_gate,
13216
+
13217
+ ocr_embedded_images: self.ocr_embedded_images,
13218
+
12979
13219
  chunking: self.chunking.clone().map(Into::into),
12980
13220
 
12981
13221
  content_filter: self.content_filter.clone().map(Into::into),
@@ -17185,6 +17425,7 @@ pub struct ImagePreprocessingConfig {
17185
17425
  contrast_enhance: bool,
17186
17426
  binarization_method: String,
17187
17427
  invert_colors: bool,
17428
+ normalize_shaded_rows: bool,
17188
17429
  }
17189
17430
 
17190
17431
  unsafe impl IntoValueFromNative for ImagePreprocessingConfig {}
@@ -17299,6 +17540,15 @@ impl ImagePreprocessingConfig {
17299
17540
  })?,
17300
17541
  None => false,
17301
17542
  },
17543
+ normalize_shaded_rows: match kwargs.get(ruby.to_symbol("normalize_shaded_rows")) {
17544
+ Some(v) => bool::try_convert(v).map_err(|e| {
17545
+ magnus::Error::new(
17546
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
17547
+ format!("invalid value for `normalize_shaded_rows`: {}", e),
17548
+ )
17549
+ })?,
17550
+ None => false,
17551
+ },
17302
17552
  })
17303
17553
  }
17304
17554
 
@@ -17329,6 +17579,10 @@ impl ImagePreprocessingConfig {
17329
17579
  fn invert_colors(&self) -> bool {
17330
17580
  self.invert_colors
17331
17581
  }
17582
+
17583
+ fn normalize_shaded_rows(&self) -> bool {
17584
+ self.normalize_shaded_rows
17585
+ }
17332
17586
  }
17333
17587
 
17334
17588
  #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
@@ -21851,6 +22105,7 @@ pub struct OcrConfig {
21851
22105
  security_limits: Option<SecurityLimits>,
21852
22106
  tessdata_bytes: Option<HashMap<String, Vec<u8>>>,
21853
22107
  tessdata_path: Option<String>,
22108
+ numeric_repair: bool,
21854
22109
  }
21855
22110
 
21856
22111
  unsafe impl IntoValueFromNative for OcrConfig {}
@@ -22064,6 +22319,15 @@ impl OcrConfig {
22064
22319
  })?),
22065
22320
  None => None,
22066
22321
  },
22322
+ numeric_repair: match kwargs.get(ruby.to_symbol("numeric_repair")) {
22323
+ Some(v) => bool::try_convert(v).map_err(|e| {
22324
+ magnus::Error::new(
22325
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
22326
+ format!("invalid value for `numeric_repair`: {}", e),
22327
+ )
22328
+ })?,
22329
+ None => false,
22330
+ },
22067
22331
  })
22068
22332
  }
22069
22333
 
@@ -22138,6 +22402,10 @@ impl OcrConfig {
22138
22402
  fn tessdata_path(&self) -> Option<String> {
22139
22403
  self.tessdata_path.clone()
22140
22404
  }
22405
+
22406
+ fn numeric_repair(&self) -> bool {
22407
+ self.numeric_repair
22408
+ }
22141
22409
  }
22142
22410
 
22143
22411
  #[derive(Clone, Debug, serde::Serialize)]
@@ -32875,7 +33143,7 @@ pub struct TesseractConfig {
32875
33143
  tessedit_char_blacklist: String,
32876
33144
  tessedit_use_primary_params_model: bool,
32877
33145
  textord_space_size_is_variable: bool,
32878
- thresholding_method: bool,
33146
+ thresholding_method: i32,
32879
33147
  }
32880
33148
 
32881
33149
  unsafe impl IntoValueFromNative for TesseractConfig {}
@@ -33108,13 +33376,13 @@ impl TesseractConfig {
33108
33376
  None => true,
33109
33377
  },
33110
33378
  thresholding_method: match kwargs.get(ruby.to_symbol("thresholding_method")) {
33111
- Some(v) => bool::try_convert(v).map_err(|e| {
33379
+ Some(v) => i32::try_convert(v).map_err(|e| {
33112
33380
  magnus::Error::new(
33113
33381
  unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
33114
33382
  format!("invalid value for `thresholding_method`: {}", e),
33115
33383
  )
33116
33384
  })?,
33117
- None => false,
33385
+ None => 0,
33118
33386
  },
33119
33387
  })
33120
33388
  }
@@ -33199,7 +33467,7 @@ impl TesseractConfig {
33199
33467
  self.textord_space_size_is_variable
33200
33468
  }
33201
33469
 
33202
- fn thresholding_method(&self) -> bool {
33470
+ fn thresholding_method(&self) -> i32 {
33203
33471
  self.thresholding_method
33204
33472
  }
33205
33473
  }
@@ -42468,6 +42736,31 @@ fn list_ocr_backend_capabilities() -> Result<Vec<OcrBackendCapabilities>, Error>
42468
42736
  Ok(result.into_iter().map(Into::into).collect())
42469
42737
  }
42470
42738
 
42739
+ fn list_ocr_backend_capabilities_for(args: &[magnus::Value]) -> Result<Vec<OcrBackendCapabilities>, Error> {
42740
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::Value>,), (), (), (), ()>(args)?;
42741
+ let (config,) = args.optional;
42742
+
42743
+ let config_core: xberg::OcrConfig = match config {
42744
+ Some(_v) if !_v.is_nil() => {
42745
+ let binding_val: OcrConfig = OcrConfig::try_convert(_v).map_err(|e| {
42746
+ magnus::Error::new(
42747
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
42748
+ e.to_string(),
42749
+ )
42750
+ })?;
42751
+ binding_val.into()
42752
+ }
42753
+ _ => Default::default(),
42754
+ };
42755
+ let result = xberg::list_ocr_backend_capabilities_for(&config_core).map_err(|e| {
42756
+ magnus::Error::new(
42757
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
42758
+ e.to_string(),
42759
+ )
42760
+ })?;
42761
+ Ok(result.into_iter().map(Into::into).collect())
42762
+ }
42763
+
42471
42764
  fn list_ocr_backends() -> Result<Vec<String>, Error> {
42472
42765
  let result = xberg::list_ocr_backends().map_err(|e| {
42473
42766
  magnus::Error::new(
@@ -42653,6 +42946,57 @@ fn ocr_backend_supports_language(backend: String, language: String) -> Result<bo
42653
42946
  Ok(result)
42654
42947
  }
42655
42948
 
42949
+ fn ocr_backend_supports_language_for(args: &[magnus::Value]) -> Result<bool, Error> {
42950
+ let args = magnus::scan_args::scan_args::<(String, String), (Option<magnus::Value>,), (), (), (), ()>(args)?;
42951
+ let (backend, language) = args.required;
42952
+
42953
+ let (config,) = args.optional;
42954
+
42955
+ let config_core: xberg::OcrConfig = match config {
42956
+ Some(_v) if !_v.is_nil() => {
42957
+ let binding_val: OcrConfig = OcrConfig::try_convert(_v).map_err(|e| {
42958
+ magnus::Error::new(
42959
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
42960
+ e.to_string(),
42961
+ )
42962
+ })?;
42963
+ binding_val.into()
42964
+ }
42965
+ _ => Default::default(),
42966
+ };
42967
+ let result = xberg::ocr_backend_supports_language_for(&backend, &language, &config_core).map_err(|e| {
42968
+ magnus::Error::new(
42969
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
42970
+ e.to_string(),
42971
+ )
42972
+ })?;
42973
+ Ok(result)
42974
+ }
42975
+
42976
+ #[cfg(feature = "pdf")]
42977
+ fn pdf_page_count(args: &[magnus::Value]) -> Result<usize, Error> {
42978
+ let args = magnus::scan_args::scan_args::<(Vec<u8>,), (Option<magnus::Value>,), (), (), (), ()>(args)?;
42979
+ let (pdf_bytes,) = args.required;
42980
+
42981
+ let (password,) = args.optional;
42982
+
42983
+ let password: Option<String> = password.and_then(|v| {
42984
+ if v.is_nil() {
42985
+ None
42986
+ } else {
42987
+ Some(String::try_convert(v).unwrap_or_default())
42988
+ }
42989
+ });
42990
+
42991
+ let result = xberg::pdf_page_count(&pdf_bytes, password.as_deref()).map_err(|e| {
42992
+ magnus::Error::new(
42993
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
42994
+ e.to_string(),
42995
+ )
42996
+ })?;
42997
+ Ok(result)
42998
+ }
42999
+
42656
43000
  #[cfg(feature = "markdown-footnotes")]
42657
43001
  fn verify_excerpt(excerpt: String, source_text: String) -> bool {
42658
43002
  xberg::verify_excerpt(&excerpt, &source_text)
@@ -42761,6 +43105,8 @@ pub struct RbOcrBackendBridge {
42761
43105
  cached_name: String,
42762
43106
  has_process_image_file: bool,
42763
43107
  has_supported_languages: bool,
43108
+ has_supported_languages_for: bool,
43109
+ has_supports_language_for: bool,
42764
43110
  has_supports_table_detection: bool,
42765
43111
  has_supports_document_processing: bool,
42766
43112
  has_emits_structured_markdown: bool,
@@ -42813,6 +43159,8 @@ impl RbOcrBackendBridge {
42813
43159
  runtime_dispatcher,
42814
43160
  has_process_image_file: rb_obj.respond_to("process_image_file", false).unwrap_or(false),
42815
43161
  has_supported_languages: rb_obj.respond_to("supported_languages", false).unwrap_or(false),
43162
+ has_supported_languages_for: rb_obj.respond_to("supported_languages_for", false).unwrap_or(false),
43163
+ has_supports_language_for: rb_obj.respond_to("supports_language_for", false).unwrap_or(false),
42816
43164
  has_supports_table_detection: rb_obj.respond_to("supports_table_detection", false).unwrap_or(false),
42817
43165
  has_supports_document_processing: rb_obj
42818
43166
  .respond_to("supports_document_processing", false)
@@ -43139,6 +43487,88 @@ impl xberg::OcrBackend for RbOcrBackendBridge {
43139
43487
  }
43140
43488
  }
43141
43489
 
43490
+ fn supported_languages_for(&self, config: &xberg::OcrConfig) -> Vec<String> {
43491
+ if !(self.has_supported_languages_for) {
43492
+ return RbOcrBackendBridgeDefaultSupportedLanguagesFor(self).supported_languages_for(config);
43493
+ }
43494
+ let config = config.clone();
43495
+ let callback = move |ruby: &magnus::Ruby, value: magnus::Value| -> Vec<String> {
43496
+ let val: magnus::Value = match value.funcall::<_, _, magnus::Value>(
43497
+ "supported_languages_for",
43498
+ ({
43499
+ use magnus::IntoValue;
43500
+ OcrConfig::from(config.clone()).into_value_with(&ruby)
43501
+ },),
43502
+ ) {
43503
+ Ok(v) => v,
43504
+ Err(e) => {
43505
+ // This method's Rust signature is infallible, so a Ruby exception cannot
43506
+ // propagate. Log before substituting the default — a silent default is
43507
+ // indistinguishable from a real result to the caller.
43508
+ tracing::warn!(wrapper = "RbOcrBackendBridge", method = "supported_languages_for", error = %e, "host callback raised; returning default");
43509
+ return Default::default();
43510
+ }
43511
+ };
43512
+ <Vec<String> as magnus::TryConvert>::try_convert(val).unwrap_or_else(|e| {
43513
+ tracing::warn!(wrapper = "RbOcrBackendBridge", method = "supported_languages_for", error = %e, "host returned an unconvertible value; returning default");
43514
+ Default::default()
43515
+ })
43516
+ };
43517
+ match magnus::Ruby::get() {
43518
+ Ok(ruby) => callback(&ruby, self.inner.get_inner_with(&ruby)),
43519
+ Err(_) => match self.runtime_dispatcher.dispatch(callback) {
43520
+ Ok(result) => result,
43521
+ Err(error) => {
43522
+ tracing::warn!(wrapper = "RbOcrBackendBridge", method = "supported_languages_for", %error, "Ruby runtime dispatcher failed; returning default");
43523
+ Default::default()
43524
+ }
43525
+ },
43526
+ }
43527
+ }
43528
+
43529
+ fn supports_language_for(&self, config: &xberg::OcrConfig, language: &str) -> bool {
43530
+ if !(self.has_supports_language_for) {
43531
+ return RbOcrBackendBridgeDefaultSupportsLanguageFor(self).supports_language_for(config, language);
43532
+ }
43533
+ let config = config.clone();
43534
+ let language = language.to_string();
43535
+ let callback = move |ruby: &magnus::Ruby, value: magnus::Value| -> bool {
43536
+ let val: magnus::Value = match value.funcall::<_, _, magnus::Value>(
43537
+ "supports_language_for",
43538
+ (
43539
+ {
43540
+ use magnus::IntoValue;
43541
+ OcrConfig::from(config.clone()).into_value_with(&ruby)
43542
+ },
43543
+ ruby.str_new(AsRef::<str>::as_ref(&language)).as_value(),
43544
+ ),
43545
+ ) {
43546
+ Ok(v) => v,
43547
+ Err(e) => {
43548
+ // This method's Rust signature is infallible, so a Ruby exception cannot
43549
+ // propagate. Log before substituting the default — a silent default is
43550
+ // indistinguishable from a real result to the caller.
43551
+ tracing::warn!(wrapper = "RbOcrBackendBridge", method = "supports_language_for", error = %e, "host callback raised; returning default");
43552
+ return Default::default();
43553
+ }
43554
+ };
43555
+ <bool as magnus::TryConvert>::try_convert(val).unwrap_or_else(|e| {
43556
+ tracing::warn!(wrapper = "RbOcrBackendBridge", method = "supports_language_for", error = %e, "host returned an unconvertible value; returning default");
43557
+ Default::default()
43558
+ })
43559
+ };
43560
+ match magnus::Ruby::get() {
43561
+ Ok(ruby) => callback(&ruby, self.inner.get_inner_with(&ruby)),
43562
+ Err(_) => match self.runtime_dispatcher.dispatch(callback) {
43563
+ Ok(result) => result,
43564
+ Err(error) => {
43565
+ tracing::warn!(wrapper = "RbOcrBackendBridge", method = "supports_language_for", %error, "Ruby runtime dispatcher failed; returning default");
43566
+ Default::default()
43567
+ }
43568
+ },
43569
+ }
43570
+ }
43571
+
43142
43572
  fn supports_table_detection(&self) -> bool {
43143
43573
  if !(self.has_supports_table_detection) {
43144
43574
  return RbOcrBackendBridgeDefaultSupportsTableDetection(self).supports_table_detection();
@@ -43421,6 +43851,12 @@ impl xberg::OcrBackend for RbOcrBackendBridgeDefaultProcessImageFile<'_> {
43421
43851
  fn supported_languages(&self) -> Vec<String> {
43422
43852
  xberg::OcrBackend::supported_languages(self.0)
43423
43853
  }
43854
+ fn supported_languages_for(&self, config: &xberg::OcrConfig) -> Vec<String> {
43855
+ xberg::OcrBackend::supported_languages_for(self.0, config)
43856
+ }
43857
+ fn supports_language_for(&self, config: &xberg::OcrConfig, language: &str) -> bool {
43858
+ xberg::OcrBackend::supports_language_for(self.0, config, language)
43859
+ }
43424
43860
  fn supports_table_detection(&self) -> bool {
43425
43861
  xberg::OcrBackend::supports_table_detection(self.0)
43426
43862
  }
@@ -43489,6 +43925,160 @@ impl xberg::OcrBackend for RbOcrBackendBridgeDefaultSupportedLanguages<'_> {
43489
43925
  fn backend_type(&self) -> xberg::OcrBackendType {
43490
43926
  xberg::OcrBackend::backend_type(self.0)
43491
43927
  }
43928
+ fn supported_languages_for(&self, config: &xberg::OcrConfig) -> Vec<String> {
43929
+ xberg::OcrBackend::supported_languages_for(self.0, config)
43930
+ }
43931
+ fn supports_language_for(&self, config: &xberg::OcrConfig, language: &str) -> bool {
43932
+ xberg::OcrBackend::supports_language_for(self.0, config, language)
43933
+ }
43934
+ fn supports_table_detection(&self) -> bool {
43935
+ xberg::OcrBackend::supports_table_detection(self.0)
43936
+ }
43937
+ fn supports_document_processing(&self) -> bool {
43938
+ xberg::OcrBackend::supports_document_processing(self.0)
43939
+ }
43940
+ fn emits_structured_markdown(&self) -> bool {
43941
+ xberg::OcrBackend::emits_structured_markdown(self.0)
43942
+ }
43943
+ fn confidence_semantics(&self) -> xberg::ConfidenceSemantics {
43944
+ xberg::OcrBackend::confidence_semantics(self.0)
43945
+ }
43946
+ fn page_orientation_handling(&self) -> xberg::PageOrientationHandling {
43947
+ xberg::OcrBackend::page_orientation_handling(self.0)
43948
+ }
43949
+ async fn process_document(
43950
+ &self,
43951
+ _path: &std::path::Path,
43952
+ _config: &xberg::OcrConfig,
43953
+ ) -> std::result::Result<xberg::ExtractedDocument, xberg::XbergError> {
43954
+ xberg::OcrBackend::process_document(self.0, _path, _config).await
43955
+ }
43956
+ }
43957
+
43958
+ /// Runs `supported_languages_for`'s Rust default body for [`RbOcrBackendBridge`] while routing
43959
+ /// every other trait method back through the bridge, so the default body's `self.*`
43960
+ /// calls still reach host overrides.
43961
+ #[derive(Debug)]
43962
+ struct RbOcrBackendBridgeDefaultSupportedLanguagesFor<'a>(&'a RbOcrBackendBridge);
43963
+ impl xberg::plugins::Plugin for RbOcrBackendBridgeDefaultSupportedLanguagesFor<'_> {
43964
+ fn name(&self) -> &str {
43965
+ xberg::plugins::Plugin::name(self.0)
43966
+ }
43967
+
43968
+ fn version(&self) -> String {
43969
+ xberg::plugins::Plugin::version(self.0)
43970
+ }
43971
+
43972
+ fn initialize(&self) -> std::result::Result<(), xberg::XbergError> {
43973
+ xberg::plugins::Plugin::initialize(self.0)
43974
+ }
43975
+
43976
+ fn shutdown(&self) -> std::result::Result<(), xberg::XbergError> {
43977
+ xberg::plugins::Plugin::shutdown(self.0)
43978
+ }
43979
+ }
43980
+ #[async_trait::async_trait]
43981
+ impl xberg::OcrBackend for RbOcrBackendBridgeDefaultSupportedLanguagesFor<'_> {
43982
+ async fn process_image(
43983
+ &self,
43984
+ image_bytes: &[u8],
43985
+ config: &xberg::OcrConfig,
43986
+ ) -> std::result::Result<xberg::ExtractedDocument, xberg::XbergError> {
43987
+ xberg::OcrBackend::process_image(self.0, image_bytes, config).await
43988
+ }
43989
+ async fn process_image_file(
43990
+ &self,
43991
+ path: &std::path::Path,
43992
+ config: &xberg::OcrConfig,
43993
+ ) -> std::result::Result<xberg::ExtractedDocument, xberg::XbergError> {
43994
+ xberg::OcrBackend::process_image_file(self.0, path, config).await
43995
+ }
43996
+ fn supports_language(&self, lang: &str) -> bool {
43997
+ xberg::OcrBackend::supports_language(self.0, lang)
43998
+ }
43999
+ fn backend_type(&self) -> xberg::OcrBackendType {
44000
+ xberg::OcrBackend::backend_type(self.0)
44001
+ }
44002
+ fn supported_languages(&self) -> Vec<String> {
44003
+ xberg::OcrBackend::supported_languages(self.0)
44004
+ }
44005
+ fn supports_language_for(&self, config: &xberg::OcrConfig, language: &str) -> bool {
44006
+ xberg::OcrBackend::supports_language_for(self.0, config, language)
44007
+ }
44008
+ fn supports_table_detection(&self) -> bool {
44009
+ xberg::OcrBackend::supports_table_detection(self.0)
44010
+ }
44011
+ fn supports_document_processing(&self) -> bool {
44012
+ xberg::OcrBackend::supports_document_processing(self.0)
44013
+ }
44014
+ fn emits_structured_markdown(&self) -> bool {
44015
+ xberg::OcrBackend::emits_structured_markdown(self.0)
44016
+ }
44017
+ fn confidence_semantics(&self) -> xberg::ConfidenceSemantics {
44018
+ xberg::OcrBackend::confidence_semantics(self.0)
44019
+ }
44020
+ fn page_orientation_handling(&self) -> xberg::PageOrientationHandling {
44021
+ xberg::OcrBackend::page_orientation_handling(self.0)
44022
+ }
44023
+ async fn process_document(
44024
+ &self,
44025
+ _path: &std::path::Path,
44026
+ _config: &xberg::OcrConfig,
44027
+ ) -> std::result::Result<xberg::ExtractedDocument, xberg::XbergError> {
44028
+ xberg::OcrBackend::process_document(self.0, _path, _config).await
44029
+ }
44030
+ }
44031
+
44032
+ /// Runs `supports_language_for`'s Rust default body for [`RbOcrBackendBridge`] while routing
44033
+ /// every other trait method back through the bridge, so the default body's `self.*`
44034
+ /// calls still reach host overrides.
44035
+ #[derive(Debug)]
44036
+ struct RbOcrBackendBridgeDefaultSupportsLanguageFor<'a>(&'a RbOcrBackendBridge);
44037
+ impl xberg::plugins::Plugin for RbOcrBackendBridgeDefaultSupportsLanguageFor<'_> {
44038
+ fn name(&self) -> &str {
44039
+ xberg::plugins::Plugin::name(self.0)
44040
+ }
44041
+
44042
+ fn version(&self) -> String {
44043
+ xberg::plugins::Plugin::version(self.0)
44044
+ }
44045
+
44046
+ fn initialize(&self) -> std::result::Result<(), xberg::XbergError> {
44047
+ xberg::plugins::Plugin::initialize(self.0)
44048
+ }
44049
+
44050
+ fn shutdown(&self) -> std::result::Result<(), xberg::XbergError> {
44051
+ xberg::plugins::Plugin::shutdown(self.0)
44052
+ }
44053
+ }
44054
+ #[async_trait::async_trait]
44055
+ impl xberg::OcrBackend for RbOcrBackendBridgeDefaultSupportsLanguageFor<'_> {
44056
+ async fn process_image(
44057
+ &self,
44058
+ image_bytes: &[u8],
44059
+ config: &xberg::OcrConfig,
44060
+ ) -> std::result::Result<xberg::ExtractedDocument, xberg::XbergError> {
44061
+ xberg::OcrBackend::process_image(self.0, image_bytes, config).await
44062
+ }
44063
+ async fn process_image_file(
44064
+ &self,
44065
+ path: &std::path::Path,
44066
+ config: &xberg::OcrConfig,
44067
+ ) -> std::result::Result<xberg::ExtractedDocument, xberg::XbergError> {
44068
+ xberg::OcrBackend::process_image_file(self.0, path, config).await
44069
+ }
44070
+ fn supports_language(&self, lang: &str) -> bool {
44071
+ xberg::OcrBackend::supports_language(self.0, lang)
44072
+ }
44073
+ fn backend_type(&self) -> xberg::OcrBackendType {
44074
+ xberg::OcrBackend::backend_type(self.0)
44075
+ }
44076
+ fn supported_languages(&self) -> Vec<String> {
44077
+ xberg::OcrBackend::supported_languages(self.0)
44078
+ }
44079
+ fn supported_languages_for(&self, config: &xberg::OcrConfig) -> Vec<String> {
44080
+ xberg::OcrBackend::supported_languages_for(self.0, config)
44081
+ }
43492
44082
  fn supports_table_detection(&self) -> bool {
43493
44083
  xberg::OcrBackend::supports_table_detection(self.0)
43494
44084
  }
@@ -43560,6 +44150,12 @@ impl xberg::OcrBackend for RbOcrBackendBridgeDefaultSupportsTableDetection<'_> {
43560
44150
  fn supported_languages(&self) -> Vec<String> {
43561
44151
  xberg::OcrBackend::supported_languages(self.0)
43562
44152
  }
44153
+ fn supported_languages_for(&self, config: &xberg::OcrConfig) -> Vec<String> {
44154
+ xberg::OcrBackend::supported_languages_for(self.0, config)
44155
+ }
44156
+ fn supports_language_for(&self, config: &xberg::OcrConfig, language: &str) -> bool {
44157
+ xberg::OcrBackend::supports_language_for(self.0, config, language)
44158
+ }
43563
44159
  fn supports_document_processing(&self) -> bool {
43564
44160
  xberg::OcrBackend::supports_document_processing(self.0)
43565
44161
  }
@@ -43628,6 +44224,12 @@ impl xberg::OcrBackend for RbOcrBackendBridgeDefaultSupportsDocumentProcessing<'
43628
44224
  fn supported_languages(&self) -> Vec<String> {
43629
44225
  xberg::OcrBackend::supported_languages(self.0)
43630
44226
  }
44227
+ fn supported_languages_for(&self, config: &xberg::OcrConfig) -> Vec<String> {
44228
+ xberg::OcrBackend::supported_languages_for(self.0, config)
44229
+ }
44230
+ fn supports_language_for(&self, config: &xberg::OcrConfig, language: &str) -> bool {
44231
+ xberg::OcrBackend::supports_language_for(self.0, config, language)
44232
+ }
43631
44233
  fn supports_table_detection(&self) -> bool {
43632
44234
  xberg::OcrBackend::supports_table_detection(self.0)
43633
44235
  }
@@ -43696,6 +44298,12 @@ impl xberg::OcrBackend for RbOcrBackendBridgeDefaultEmitsStructuredMarkdown<'_>
43696
44298
  fn supported_languages(&self) -> Vec<String> {
43697
44299
  xberg::OcrBackend::supported_languages(self.0)
43698
44300
  }
44301
+ fn supported_languages_for(&self, config: &xberg::OcrConfig) -> Vec<String> {
44302
+ xberg::OcrBackend::supported_languages_for(self.0, config)
44303
+ }
44304
+ fn supports_language_for(&self, config: &xberg::OcrConfig, language: &str) -> bool {
44305
+ xberg::OcrBackend::supports_language_for(self.0, config, language)
44306
+ }
43699
44307
  fn supports_table_detection(&self) -> bool {
43700
44308
  xberg::OcrBackend::supports_table_detection(self.0)
43701
44309
  }
@@ -43764,6 +44372,12 @@ impl xberg::OcrBackend for RbOcrBackendBridgeDefaultConfidenceSemantics<'_> {
43764
44372
  fn supported_languages(&self) -> Vec<String> {
43765
44373
  xberg::OcrBackend::supported_languages(self.0)
43766
44374
  }
44375
+ fn supported_languages_for(&self, config: &xberg::OcrConfig) -> Vec<String> {
44376
+ xberg::OcrBackend::supported_languages_for(self.0, config)
44377
+ }
44378
+ fn supports_language_for(&self, config: &xberg::OcrConfig, language: &str) -> bool {
44379
+ xberg::OcrBackend::supports_language_for(self.0, config, language)
44380
+ }
43767
44381
  fn supports_table_detection(&self) -> bool {
43768
44382
  xberg::OcrBackend::supports_table_detection(self.0)
43769
44383
  }
@@ -43832,6 +44446,12 @@ impl xberg::OcrBackend for RbOcrBackendBridgeDefaultPageOrientationHandling<'_>
43832
44446
  fn supported_languages(&self) -> Vec<String> {
43833
44447
  xberg::OcrBackend::supported_languages(self.0)
43834
44448
  }
44449
+ fn supported_languages_for(&self, config: &xberg::OcrConfig) -> Vec<String> {
44450
+ xberg::OcrBackend::supported_languages_for(self.0, config)
44451
+ }
44452
+ fn supports_language_for(&self, config: &xberg::OcrConfig, language: &str) -> bool {
44453
+ xberg::OcrBackend::supports_language_for(self.0, config, language)
44454
+ }
43835
44455
  fn supports_table_detection(&self) -> bool {
43836
44456
  xberg::OcrBackend::supports_table_detection(self.0)
43837
44457
  }
@@ -43900,6 +44520,12 @@ impl xberg::OcrBackend for RbOcrBackendBridgeDefaultProcessDocument<'_> {
43900
44520
  fn supported_languages(&self) -> Vec<String> {
43901
44521
  xberg::OcrBackend::supported_languages(self.0)
43902
44522
  }
44523
+ fn supported_languages_for(&self, config: &xberg::OcrConfig) -> Vec<String> {
44524
+ xberg::OcrBackend::supported_languages_for(self.0, config)
44525
+ }
44526
+ fn supports_language_for(&self, config: &xberg::OcrConfig, language: &str) -> bool {
44527
+ xberg::OcrBackend::supports_language_for(self.0, config, language)
44528
+ }
43903
44529
  fn supports_table_detection(&self) -> bool {
43904
44530
  xberg::OcrBackend::supports_table_detection(self.0)
43905
44531
  }
@@ -47047,6 +47673,8 @@ impl From<BrowserConfig> for crawlberg::BrowserConfig {
47047
47673
  backend: val.backend.into(),
47048
47674
  endpoint: val.endpoint,
47049
47675
  timeout: std::time::Duration::from_millis(val.timeout),
47676
+ overall_timeout: std::time::Duration::from_millis(val.overall_timeout),
47677
+ shutdown_timeout: std::time::Duration::from_millis(val.shutdown_timeout),
47050
47678
  wait: val.wait.into(),
47051
47679
  wait_selector: val.wait_selector,
47052
47680
  extra_wait: val.extra_wait.map(std::time::Duration::from_millis),
@@ -47069,6 +47697,8 @@ impl From<crawlberg::BrowserConfig> for BrowserConfig {
47069
47697
  backend: val.backend.into(),
47070
47698
  endpoint: val.endpoint.map(|v| v.to_string()),
47071
47699
  timeout: val.timeout.as_millis() as u64,
47700
+ overall_timeout: val.overall_timeout.as_millis() as u64,
47701
+ shutdown_timeout: val.shutdown_timeout.as_millis() as u64,
47072
47702
  wait: val.wait.into(),
47073
47703
  wait_selector: val.wait_selector.map(|v| v.to_string()),
47074
47704
  extra_wait: val.extra_wait.map(|d| d.as_millis() as u64),
@@ -47530,6 +48160,7 @@ impl From<ContentConfig> for crawlberg::ContentConfig {
47530
48160
  wrap: val.wrap,
47531
48161
  wrap_width: val.wrap_width,
47532
48162
  include_document_structure: val.include_document_structure,
48163
+ extract_metadata: val.extract_metadata,
47533
48164
  ..Default::default()
47534
48165
  }
47535
48166
  }
@@ -47550,6 +48181,7 @@ impl From<crawlberg::ContentConfig> for ContentConfig {
47550
48181
  wrap: val.wrap,
47551
48182
  wrap_width: val.wrap_width,
47552
48183
  include_document_structure: val.include_document_structure,
48184
+ extract_metadata: val.extract_metadata,
47553
48185
  }
47554
48186
  }
47555
48187
  }
@@ -47647,12 +48279,13 @@ impl From<ConversionOptions> for html_to_markdown_rs::ConversionOptions {
47647
48279
  max_depth: val.max_depth,
47648
48280
  exclude_selectors: val.exclude_selectors.into_iter().collect(),
47649
48281
  tier_strategy: val.tier_strategy.into(),
48282
+ base_url: val.base_url,
47650
48283
  ..Default::default()
47651
48284
  }
47652
48285
  }
47653
48286
  }
47654
48287
 
47655
- #[allow(clippy::useless_conversion)]
48288
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
47656
48289
  impl From<html_to_markdown_rs::ConversionOptions> for ConversionOptions {
47657
48290
  fn from(val: html_to_markdown_rs::ConversionOptions) -> Self {
47658
48291
  Self {
@@ -47699,6 +48332,7 @@ impl From<html_to_markdown_rs::ConversionOptions> for ConversionOptions {
47699
48332
  max_depth: val.max_depth,
47700
48333
  exclude_selectors: val.exclude_selectors.into_iter().collect(),
47701
48334
  tier_strategy: val.tier_strategy.into(),
48335
+ base_url: val.base_url.map(|v| v.to_string()),
47702
48336
  }
47703
48337
  }
47704
48338
  }
@@ -47772,6 +48406,10 @@ impl From<CrawlConfig> for crawlberg::CrawlConfig {
47772
48406
  allow_subdomains: val.allow_subdomains,
47773
48407
  include_paths: val.include_paths.into_iter().collect(),
47774
48408
  exclude_paths: val.exclude_paths.into_iter().collect(),
48409
+ path_patterns_match_query: val.path_patterns_match_query,
48410
+ dedup_include_query: val.dedup_include_query,
48411
+ strip_tracking_params: val.strip_tracking_params,
48412
+ tracking_params: val.tracking_params.into_iter().collect(),
47775
48413
  custom_headers: val
47776
48414
  .custom_headers
47777
48415
  .into_iter()
@@ -47782,6 +48420,9 @@ impl From<CrawlConfig> for crawlberg::CrawlConfig {
47782
48420
  max_redirects: val.max_redirects,
47783
48421
  retry_count: val.retry_count,
47784
48422
  retry_codes: val.retry_codes.into_iter().collect(),
48423
+ retry_initial_delay_ms: val.retry_initial_delay_ms,
48424
+ retry_max_delay_ms: val.retry_max_delay_ms,
48425
+ rate_limit_jitter_ratio: val.rate_limit_jitter_ratio,
47785
48426
  cookies_enabled: val.cookies_enabled,
47786
48427
  auth: val.auth.map(Into::into),
47787
48428
  max_body_size: val.max_body_size,
@@ -47832,6 +48473,10 @@ impl From<crawlberg::CrawlConfig> for CrawlConfig {
47832
48473
  allow_subdomains: val.allow_subdomains,
47833
48474
  include_paths: val.include_paths.into_iter().collect(),
47834
48475
  exclude_paths: val.exclude_paths.into_iter().collect(),
48476
+ path_patterns_match_query: val.path_patterns_match_query,
48477
+ dedup_include_query: val.dedup_include_query,
48478
+ strip_tracking_params: val.strip_tracking_params,
48479
+ tracking_params: val.tracking_params.into_iter().collect(),
47835
48480
  custom_headers: val
47836
48481
  .custom_headers
47837
48482
  .into_iter()
@@ -47842,6 +48487,9 @@ impl From<crawlberg::CrawlConfig> for CrawlConfig {
47842
48487
  max_redirects: val.max_redirects,
47843
48488
  retry_count: val.retry_count,
47844
48489
  retry_codes: val.retry_codes.into_iter().collect(),
48490
+ retry_initial_delay_ms: val.retry_initial_delay_ms,
48491
+ retry_max_delay_ms: val.retry_max_delay_ms,
48492
+ rate_limit_jitter_ratio: val.rate_limit_jitter_ratio,
47845
48493
  cookies_enabled: val.cookies_enabled,
47846
48494
  auth: val.auth.map(Into::into),
47847
48495
  max_body_size: val.max_body_size,
@@ -49044,6 +49692,9 @@ impl From<ExtractionConfig> for xberg::ExtractionConfig {
49044
49692
  ocr_strategy: val.ocr_strategy.into(),
49045
49693
  force_ocr_pages: val.force_ocr_pages.map(|v| v.into_iter().collect()),
49046
49694
  disable_ocr: val.disable_ocr,
49695
+ ocr_near_empty_fallback: val.ocr_near_empty_fallback,
49696
+ ocr_scanned_page_quality_gate: val.ocr_scanned_page_quality_gate,
49697
+ ocr_embedded_images: val.ocr_embedded_images,
49047
49698
  chunking: val.chunking.map(Into::into),
49048
49699
  content_filter: val.content_filter.map(Into::into),
49049
49700
  images: val.images.map(Into::into),
@@ -49112,6 +49763,9 @@ impl From<xberg::ExtractionConfig> for ExtractionConfig {
49112
49763
  ocr_strategy: val.ocr_strategy.into(),
49113
49764
  force_ocr_pages: val.force_ocr_pages.map(|v| v.into_iter().collect()),
49114
49765
  disable_ocr: val.disable_ocr,
49766
+ ocr_near_empty_fallback: val.ocr_near_empty_fallback,
49767
+ ocr_scanned_page_quality_gate: val.ocr_scanned_page_quality_gate,
49768
+ ocr_embedded_images: val.ocr_embedded_images,
49115
49769
  chunking: val.chunking.map(Into::into),
49116
49770
  content_filter: val.content_filter.map(Into::into),
49117
49771
  images: val.images.map(Into::into),
@@ -49987,6 +50641,7 @@ impl From<ImagePreprocessingConfig> for xberg::ImagePreprocessingConfig {
49987
50641
  contrast_enhance: val.contrast_enhance,
49988
50642
  binarization_method: val.binarization_method,
49989
50643
  invert_colors: val.invert_colors,
50644
+ normalize_shaded_rows: val.normalize_shaded_rows,
49990
50645
  ..Default::default()
49991
50646
  }
49992
50647
  }
@@ -50002,6 +50657,7 @@ impl From<xberg::ImagePreprocessingConfig> for ImagePreprocessingConfig {
50002
50657
  contrast_enhance: val.contrast_enhance,
50003
50658
  binarization_method: val.binarization_method.to_string(),
50004
50659
  invert_colors: val.invert_colors,
50660
+ normalize_shaded_rows: val.normalize_shaded_rows,
50005
50661
  }
50006
50662
  }
50007
50663
  }
@@ -50937,6 +51593,7 @@ impl From<OcrConfig> for xberg::OcrConfig {
50937
51593
  .tessdata_bytes
50938
51594
  .map(|m| m.into_iter().map(|(k, v)| (k, v.to_vec().into())).collect()),
50939
51595
  tessdata_path: val.tessdata_path.map(Into::into),
51596
+ numeric_repair: val.numeric_repair,
50940
51597
  ..Default::default()
50941
51598
  }
50942
51599
  }
@@ -50966,6 +51623,7 @@ impl From<xberg::OcrConfig> for OcrConfig {
50966
51623
  .tessdata_bytes
50967
51624
  .map(|m| m.into_iter().map(|(k, v)| (k, v.to_vec().into())).collect()),
50968
51625
  tessdata_path: val.tessdata_path.map(|p| p.to_string_lossy().to_string()),
51626
+ numeric_repair: val.numeric_repair,
50969
51627
  }
50970
51628
  }
50971
51629
  }
@@ -56167,6 +56825,10 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
56167
56825
 
56168
56826
  class.define_method("timeout", method!(BrowserConfig::timeout, 0))?;
56169
56827
 
56828
+ class.define_method("overall_timeout", method!(BrowserConfig::overall_timeout, 0))?;
56829
+
56830
+ class.define_method("shutdown_timeout", method!(BrowserConfig::shutdown_timeout, 0))?;
56831
+
56170
56832
  class.define_method("wait", method!(BrowserConfig::wait, 0))?;
56171
56833
 
56172
56834
  class.define_method("wait_selector", method!(BrowserConfig::wait_selector, 0))?;
@@ -56504,6 +57166,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
56504
57166
  method!(ContentConfig::include_document_structure, 0),
56505
57167
  )?;
56506
57168
 
57169
+ class.define_method("extract_metadata", method!(ContentConfig::extract_metadata, 0))?;
57170
+
56507
57171
  let class = module.define_class("ContentFilterConfig", ruby.class_object())?;
56508
57172
 
56509
57173
  class.define_singleton_method("new", function!(ContentFilterConfig::new, -1))?;
@@ -56628,6 +57292,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
56628
57292
 
56629
57293
  class.define_method("tier_strategy", method!(ConversionOptions::tier_strategy, 0))?;
56630
57294
 
57295
+ class.define_method("base_url", method!(ConversionOptions::base_url, 0))?;
57296
+
56631
57297
  let class = module.define_class("CoreProperties", ruby.class_object())?;
56632
57298
 
56633
57299
  #[cfg(feature = "office")]
@@ -56712,6 +57378,17 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
56712
57378
 
56713
57379
  class.define_method("exclude_paths", method!(CrawlConfig::exclude_paths, 0))?;
56714
57380
 
57381
+ class.define_method(
57382
+ "path_patterns_match_query",
57383
+ method!(CrawlConfig::path_patterns_match_query, 0),
57384
+ )?;
57385
+
57386
+ class.define_method("dedup_include_query", method!(CrawlConfig::dedup_include_query, 0))?;
57387
+
57388
+ class.define_method("strip_tracking_params", method!(CrawlConfig::strip_tracking_params, 0))?;
57389
+
57390
+ class.define_method("tracking_params", method!(CrawlConfig::tracking_params, 0))?;
57391
+
56715
57392
  class.define_method("custom_headers", method!(CrawlConfig::custom_headers, 0))?;
56716
57393
 
56717
57394
  class.define_method("request_timeout", method!(CrawlConfig::request_timeout, 0))?;
@@ -56724,6 +57401,18 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
56724
57401
 
56725
57402
  class.define_method("retry_codes", method!(CrawlConfig::retry_codes, 0))?;
56726
57403
 
57404
+ class.define_method(
57405
+ "retry_initial_delay_ms",
57406
+ method!(CrawlConfig::retry_initial_delay_ms, 0),
57407
+ )?;
57408
+
57409
+ class.define_method("retry_max_delay_ms", method!(CrawlConfig::retry_max_delay_ms, 0))?;
57410
+
57411
+ class.define_method(
57412
+ "rate_limit_jitter_ratio",
57413
+ method!(CrawlConfig::rate_limit_jitter_ratio, 0),
57414
+ )?;
57415
+
56727
57416
  class.define_method("cookies_enabled", method!(CrawlConfig::cookies_enabled, 0))?;
56728
57417
 
56729
57418
  class.define_method("auth", method!(CrawlConfig::auth, 0))?;
@@ -57607,6 +58296,18 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
57607
58296
 
57608
58297
  class.define_method("disable_ocr", method!(ExtractionConfig::disable_ocr, 0))?;
57609
58298
 
58299
+ class.define_method(
58300
+ "ocr_near_empty_fallback",
58301
+ method!(ExtractionConfig::ocr_near_empty_fallback, 0),
58302
+ )?;
58303
+
58304
+ class.define_method(
58305
+ "ocr_scanned_page_quality_gate",
58306
+ method!(ExtractionConfig::ocr_scanned_page_quality_gate, 0),
58307
+ )?;
58308
+
58309
+ class.define_method("ocr_embedded_images", method!(ExtractionConfig::ocr_embedded_images, 0))?;
58310
+
57610
58311
  class.define_method("chunking", method!(ExtractionConfig::chunking, 0))?;
57611
58312
 
57612
58313
  class.define_method("content_filter", method!(ExtractionConfig::content_filter, 0))?;
@@ -58380,6 +59081,11 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
58380
59081
 
58381
59082
  class.define_method("invert_colors", method!(ImagePreprocessingConfig::invert_colors, 0))?;
58382
59083
 
59084
+ class.define_method(
59085
+ "normalize_shaded_rows",
59086
+ method!(ImagePreprocessingConfig::normalize_shaded_rows, 0),
59087
+ )?;
59088
+
58383
59089
  let class = module.define_class("ImagePreprocessingMetadata", ruby.class_object())?;
58384
59090
 
58385
59091
  class.define_singleton_method("new", function!(ImagePreprocessingMetadata::new, -1))?;
@@ -59008,6 +59714,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
59008
59714
 
59009
59715
  class.define_method("tessdata_path", method!(OcrConfig::tessdata_path, 0))?;
59010
59716
 
59717
+ class.define_method("numeric_repair", method!(OcrConfig::numeric_repair, 0))?;
59718
+
59011
59719
  let class = module.define_class("OcrElement", ruby.class_object())?;
59012
59720
 
59013
59721
  class.define_singleton_method("new", function!(OcrElement::new, -1))?;
@@ -60947,6 +61655,11 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
60947
61655
  function!(list_ocr_backend_capabilities, 0),
60948
61656
  )?;
60949
61657
 
61658
+ module.define_module_function(
61659
+ "list_ocr_backend_capabilities_for",
61660
+ function!(list_ocr_backend_capabilities_for, -1),
61661
+ )?;
61662
+
60950
61663
  module.define_module_function("list_ocr_backends", function!(list_ocr_backends, 0))?;
60951
61664
 
60952
61665
  module.define_module_function("list_post_processors", function!(list_post_processors, 0))?;
@@ -60981,6 +61694,14 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
60981
61694
  function!(ocr_backend_supports_language, 2),
60982
61695
  )?;
60983
61696
 
61697
+ module.define_module_function(
61698
+ "ocr_backend_supports_language_for",
61699
+ function!(ocr_backend_supports_language_for, -1),
61700
+ )?;
61701
+
61702
+ #[cfg(feature = "pdf")]
61703
+ module.define_module_function("pdf_page_count", function!(pdf_page_count, -1))?;
61704
+
60984
61705
  #[cfg(feature = "markdown-footnotes")]
60985
61706
  module.define_module_function("verify_excerpt", function!(verify_excerpt, 2))?;
60986
61707