yara_mapper_sys/lib.rs
1//! Low-level FFI bindings to the YARA read mapper C++ shim.
2//!
3//! This crate compiles a C++ shim layer that wraps YARA's SeqAn2-based template code
4//! and exposes a C-compatible API for loading FM indices, ingesting reads, and retrieving
5//! alignment results as flat structs.
6
7#![allow(non_camel_case_types)]
8
9use std::os::raw::{c_char, c_int};
10
11// ---------------------------------------------------------------------------
12// Opaque handle
13// ---------------------------------------------------------------------------
14
15/// Opaque handle to a fully-configured YARA Mapper instance.
16/// Allocated and owned by the C++ side; freed via [`yara_mapper_close`].
17#[repr(C)]
18pub struct YaraMapperHandle {
19 _opaque: [u8; 0],
20}
21
22// ---------------------------------------------------------------------------
23// Option / input / output structs (must match yara_shim.h exactly)
24// ---------------------------------------------------------------------------
25
26/// Mapper configuration passed to [`yara_mapper_open`].
27#[repr(C)]
28#[derive(Debug, Clone)]
29pub struct YaraMapperOptions {
30 pub error_rate: f32,
31 pub strata_rate: f32,
32 pub strata_count: i32,
33 pub sensitivity: i32,
34 pub threads: i32,
35 pub secondary_mode: i32,
36 pub align_secondary: i32,
37 pub verify_matches: i32,
38 pub verbose: i32,
39 pub library_length: i32,
40 pub library_dev: i32,
41}
42
43/// A batch of paired-end reads to map.
44#[repr(C)]
45#[derive(Debug)]
46pub struct YaraReadBatch {
47 pub names: *const *const c_char,
48 pub r1_seqs: *const *const c_char,
49 pub r1_quals: *const *const c_char,
50 pub r2_seqs: *const *const c_char,
51 pub r2_quals: *const *const c_char,
52 pub count: usize,
53}
54
55/// A single alignment record returned by the mapper.
56#[repr(C)]
57#[derive(Debug, Clone)]
58#[allow(clippy::pub_underscore_fields)]
59pub struct YaraAlignmentRecord {
60 // Read identification
61 pub read_pair_index: u32,
62 pub is_read1: u8,
63
64 // Alignment position
65 pub contig_id: u32,
66 pub pos: u32,
67 pub is_reverse: u8,
68 pub is_secondary: u8,
69 pub is_unmapped: u8,
70
71 // Alignment quality
72 pub mapq: u8,
73 pub nm: u8,
74 pub x0: u16,
75 pub x1: u16,
76
77 // Mate info
78 pub mate_contig_id: u32,
79 pub mate_pos: u32,
80 pub tlen: i32,
81 pub flag: u16,
82
83 // CIGAR (BAM-encoded uint32 array: op | len<<4)
84 pub cigar: *mut u32,
85 pub cigar_len: u32,
86
87 // Sequence and quality (NULL for secondaries)
88 pub seq: *const c_char,
89 pub qual: *const c_char,
90 pub seq_len: u32,
91
92 // XA tag string (NULL if none)
93 pub xa: *const c_char,
94
95 // Internal: if set, seq/qual/cigar are pool-managed (not individually freed).
96 pub _pool_managed: u8,
97}
98
99// ---------------------------------------------------------------------------
100// FFI function declarations
101// ---------------------------------------------------------------------------
102
103// SAFETY: These functions are implemented in C++ (yara_shim.cpp) and compiled
104// via build.rs. The caller is responsible for passing valid pointers and
105// respecting the lifetime contracts documented in yara_shim.h.
106unsafe extern "C" {
107 /// Create a mapper and load the FM index. Returns null on error, with
108 /// `error_buf` populated.
109 pub fn yara_mapper_open(
110 index_prefix: *const c_char,
111 opts: *const YaraMapperOptions,
112 error_buf: *mut c_char,
113 error_buf_len: usize,
114 ) -> *mut YaraMapperHandle;
115
116 /// Map a batch of paired-end reads. Returns the number of output records
117 /// written to `out`, or -1 on error.
118 pub fn yara_mapper_map_paired(
119 handle: *mut YaraMapperHandle,
120 reads: *const YaraReadBatch,
121 out: *mut YaraAlignmentRecord,
122 out_capacity: usize,
123 error_buf: *mut c_char,
124 error_buf_len: usize,
125 ) -> i64;
126
127 /// Number of reference contigs in the loaded index.
128 pub fn yara_mapper_contig_count(handle: *const YaraMapperHandle) -> usize;
129
130 /// Name of the contig at `idx`. The returned pointer is valid for the
131 /// lifetime of the handle.
132 pub fn yara_mapper_contig_name(handle: *const YaraMapperHandle, idx: usize) -> *const c_char;
133
134 /// Length of the contig at `idx`.
135 pub fn yara_mapper_contig_length(handle: *const YaraMapperHandle, idx: usize) -> usize;
136
137 /// Free the mapper and all associated memory.
138 pub fn yara_mapper_close(handle: *mut YaraMapperHandle);
139
140 /// Free a record batch's C++-owned memory (cigar arrays, seq/qual strings,
141 /// XA strings). Must be called after processing each batch.
142 pub fn yara_mapper_free_records(records: *mut YaraAlignmentRecord, count: usize);
143
144 /// Free a single record's C++-owned memory (cigar, seq, qual, xa).
145 pub fn yara_mapper_free_record(record: *mut YaraAlignmentRecord);
146}
147
148// ---------------------------------------------------------------------------
149// Indexer: opaque handle
150// ---------------------------------------------------------------------------
151
152/// Opaque handle to a YARA Indexer instance.
153/// Allocated and owned by the C++ side; freed via [`yara_indexer_close`].
154#[repr(C)]
155pub struct YaraIndexerHandle {
156 _opaque: [u8; 0],
157}
158
159// ---------------------------------------------------------------------------
160// Indexer: options struct (must match yara_indexer_shim.h exactly)
161// ---------------------------------------------------------------------------
162
163/// Indexer configuration passed to [`yara_indexer_build`].
164#[repr(C)]
165#[derive(Debug)]
166pub struct YaraIndexerOptions {
167 pub output_prefix: *const c_char,
168 pub tmp_dir: *const c_char,
169 pub verbose: c_int,
170}
171
172// ---------------------------------------------------------------------------
173// Indexer: FFI function declarations
174// ---------------------------------------------------------------------------
175
176// SAFETY: These functions are implemented in C++ (yara_indexer_shim.cpp) and
177// compiled via build.rs. The caller is responsible for passing valid pointers
178// and respecting the lifetime contracts documented in yara_indexer_shim.h.
179unsafe extern "C" {
180 /// Build an FM index from a FASTA file. Returns null on error, with
181 /// `error_buf` populated.
182 pub fn yara_indexer_build(
183 fasta_path: *const c_char,
184 opts: *const YaraIndexerOptions,
185 error_buf: *mut c_char,
186 error_buf_len: usize,
187 ) -> *mut YaraIndexerHandle;
188
189 /// Number of contigs in the built index.
190 pub fn yara_indexer_contig_count(handle: *const YaraIndexerHandle) -> usize;
191
192 /// Name of the contig at `idx`. The returned pointer is valid for the
193 /// lifetime of the handle.
194 pub fn yara_indexer_contig_name(handle: *const YaraIndexerHandle, idx: usize) -> *const c_char;
195
196 /// Length of the contig at `idx`.
197 pub fn yara_indexer_contig_length(handle: *const YaraIndexerHandle, idx: usize) -> usize;
198
199 /// Free the indexer handle and all associated memory.
200 pub fn yara_indexer_close(handle: *mut YaraIndexerHandle);
201}