Skip to main content

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}