yara_mapper/options.rs
1/// Sensitivity level for YARA's seed-and-extend pipeline.
2///
3/// - `Low`: Only two rounds of seeding (0-error and 1-error seeds).
4/// - `High`: Three rounds of seeding (adds 2-error seeds). Default.
5/// - `Full`: Same as `High` but uses edit-distance seeds instead of Hamming.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[repr(i32)]
8pub enum Sensitivity {
9 Low = 0,
10 High = 1,
11 Full = 2,
12}
13
14/// How secondary alignments are reported.
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16#[repr(i32)]
17pub enum SecondaryMode {
18 /// Encode secondary alignments in the XA tag of the primary record.
19 Tag = 0,
20 /// Emit secondary alignments as separate records with the SECONDARY flag.
21 Record = 1,
22 /// Do not report secondary alignments.
23 Omit = 2,
24}
25
26/// Configuration options for the YARA mapper.
27///
28/// Use [`MapperOptions::default()`] for sensible defaults matching YARA's
29/// command-line defaults, then override individual fields as needed.
30#[derive(Debug, Clone)]
31pub struct MapperOptions {
32 /// Maximum error rate as a fraction of read length (default 0.05 = 5%).
33 pub error_rate: f32,
34 /// Strata rate — fraction of additional errors beyond the best alignment
35 /// to report (default 0.00).
36 pub strata_rate: f32,
37 /// Fixed strata count (alternative to `strata_rate`). Set to `None` to
38 /// use `strata_rate` instead.
39 pub strata_count: Option<u32>,
40 /// Sensitivity level (default `High`).
41 pub sensitivity: Sensitivity,
42 /// Number of threads for OpenMP parallelism (default: available cores).
43 pub threads: usize,
44 /// How to report secondary alignments (default `Tag`).
45 pub secondary_mode: SecondaryMode,
46 /// Whether to align secondary matches (compute CIGAR). Only meaningful
47 /// when `secondary_mode` is `Tag` or `Record`.
48 pub align_secondary: bool,
49 /// Whether to verify mate-pair matches (paired-end rescue). Default true.
50 pub verify_matches: bool,
51 /// Verbosity level (0 = silent, 1 = stats, 2 = detailed).
52 pub verbose: u32,
53 /// Expected library (insert) length. 0 = auto-estimate from the data.
54 pub library_length: u32,
55 /// Expected library standard deviation. 0 = auto-estimate.
56 pub library_dev: u32,
57}
58
59impl Default for MapperOptions {
60 fn default() -> Self {
61 Self {
62 error_rate: 0.05,
63 strata_rate: 0.00,
64 strata_count: None,
65 sensitivity: Sensitivity::High,
66 threads: std::thread::available_parallelism().map(std::num::NonZero::get).unwrap_or(1),
67 secondary_mode: SecondaryMode::Tag,
68 align_secondary: false,
69 verify_matches: true,
70 verbose: 0,
71 library_length: 0,
72 library_dev: 0,
73 }
74 }
75}
76
77impl MapperOptions {
78 #[expect(
79 clippy::cast_possible_wrap,
80 clippy::cast_possible_truncation,
81 reason = "FFI boundary: all values fit in i32 for the C API"
82 )]
83 pub(crate) fn to_ffi(&self) -> yara_mapper_sys::YaraMapperOptions {
84 yara_mapper_sys::YaraMapperOptions {
85 error_rate: self.error_rate,
86 strata_rate: self.strata_rate,
87 strata_count: self.strata_count.map_or(-1, |c| c as i32),
88 sensitivity: self.sensitivity as i32,
89 threads: self.threads as i32,
90 secondary_mode: self.secondary_mode as i32,
91 align_secondary: i32::from(self.align_secondary),
92 verify_matches: i32::from(self.verify_matches),
93 verbose: self.verbose as i32,
94 library_length: self.library_length as i32,
95 library_dev: self.library_dev as i32,
96 }
97 }
98}