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)]
58pub struct YaraAlignmentRecord {
59 // Read identification
60 pub read_pair_index: u32,
61 pub is_read1: u8,
62
63 // Alignment position
64 pub contig_id: u32,
65 pub pos: u32,
66 pub is_reverse: u8,
67 pub is_secondary: u8,
68 pub is_unmapped: u8,
69
70 // Alignment quality
71 pub mapq: u8,
72 pub nm: u8,
73 pub x0: u16,
74 pub x1: u16,
75
76 // Mate info
77 pub mate_contig_id: u32,
78 pub mate_pos: u32,
79 pub tlen: i32,
80 pub flag: u16,
81
82 // CIGAR (BAM-encoded uint32 array: op | len<<4)
83 pub cigar: *const u32,
84 pub cigar_len: u32,
85
86 // Sequence and quality (NULL for secondaries)
87 pub seq: *const c_char,
88 pub qual: *const c_char,
89 pub seq_len: u32,
90
91 // XA tag string (NULL if none)
92 pub xa: *const c_char,
93}
94
95// ---------------------------------------------------------------------------
96// FFI function declarations
97// ---------------------------------------------------------------------------
98
99// SAFETY: These functions are implemented in C++ (yara_shim.cpp) and compiled
100// via build.rs. The caller is responsible for passing valid pointers and
101// respecting the lifetime contracts documented in yara_shim.h.
102unsafe extern "C" {
103 /// Create a mapper and load the FM index. Returns null on error, with
104 /// `error_buf` populated.
105 pub fn yara_mapper_open(
106 index_prefix: *const c_char,
107 opts: *const YaraMapperOptions,
108 error_buf: *mut c_char,
109 error_buf_len: usize,
110 ) -> *mut YaraMapperHandle;
111
112 /// Map a batch of paired-end reads. Returns the number of output records
113 /// written to `out`, or -1 on error.
114 pub fn yara_mapper_map_paired(
115 handle: *mut YaraMapperHandle,
116 reads: *const YaraReadBatch,
117 out: *mut YaraAlignmentRecord,
118 out_capacity: usize,
119 error_buf: *mut c_char,
120 error_buf_len: usize,
121 ) -> i64;
122
123 /// Number of reference contigs in the loaded index.
124 pub fn yara_mapper_contig_count(handle: *const YaraMapperHandle) -> usize;
125
126 /// Name of the contig at `idx`. The returned pointer is valid for the
127 /// lifetime of the handle.
128 pub fn yara_mapper_contig_name(handle: *const YaraMapperHandle, idx: usize) -> *const c_char;
129
130 /// Length of the contig at `idx`.
131 pub fn yara_mapper_contig_length(handle: *const YaraMapperHandle, idx: usize) -> usize;
132
133 /// Free the mapper and all associated memory.
134 pub fn yara_mapper_close(handle: *mut YaraMapperHandle);
135
136 /// Free a record batch's C++-owned memory (cigar arrays, seq/qual strings,
137 /// XA strings). Must be called after processing each batch.
138 pub fn yara_mapper_free_records(records: *mut YaraAlignmentRecord, count: usize);
139
140 /// Free a single record's C++-owned memory (cigar, seq, qual, xa).
141 pub fn yara_mapper_free_record(record: *mut YaraAlignmentRecord);
142}
143
144// ---------------------------------------------------------------------------
145// Indexer: opaque handle
146// ---------------------------------------------------------------------------
147
148/// Opaque handle to a YARA Indexer instance.
149/// Allocated and owned by the C++ side; freed via [`yara_indexer_close`].
150#[repr(C)]
151pub struct YaraIndexerHandle {
152 _opaque: [u8; 0],
153}
154
155// ---------------------------------------------------------------------------
156// Indexer: options struct (must match yara_indexer_shim.h exactly)
157// ---------------------------------------------------------------------------
158
159/// Indexer configuration passed to [`yara_indexer_build`].
160#[repr(C)]
161#[derive(Debug)]
162pub struct YaraIndexerOptions {
163 pub output_prefix: *const c_char,
164 pub tmp_dir: *const c_char,
165 pub verbose: c_int,
166}
167
168// ---------------------------------------------------------------------------
169// Indexer: FFI function declarations
170// ---------------------------------------------------------------------------
171
172// SAFETY: These functions are implemented in C++ (yara_indexer_shim.cpp) and
173// compiled via build.rs. The caller is responsible for passing valid pointers
174// and respecting the lifetime contracts documented in yara_indexer_shim.h.
175unsafe extern "C" {
176 /// Build an FM index from a FASTA file. Returns null on error, with
177 /// `error_buf` populated.
178 pub fn yara_indexer_build(
179 fasta_path: *const c_char,
180 opts: *const YaraIndexerOptions,
181 error_buf: *mut c_char,
182 error_buf_len: usize,
183 ) -> *mut YaraIndexerHandle;
184
185 /// Number of contigs in the built index.
186 pub fn yara_indexer_contig_count(handle: *const YaraIndexerHandle) -> usize;
187
188 /// Name of the contig at `idx`. The returned pointer is valid for the
189 /// lifetime of the handle.
190 pub fn yara_indexer_contig_name(handle: *const YaraIndexerHandle, idx: usize) -> *const c_char;
191
192 /// Length of the contig at `idx`.
193 pub fn yara_indexer_contig_length(handle: *const YaraIndexerHandle, idx: usize) -> usize;
194
195 /// Free the indexer handle and all associated memory.
196 pub fn yara_indexer_close(handle: *mut YaraIndexerHandle);
197}