use std::os::raw::c_char;
use std::slice;
#[repr(C)]
pub struct ContigSlice {
pub data: *mut u8,
pub len: usize,
}
#[no_mangle]
pub extern "C" fn ragc_get_contig_part(
contig_data: *const u8,
contig_len: usize,
pos: u64,
len: u64,
) -> ContigSlice {
unsafe {
let contig = slice::from_raw_parts(contig_data, contig_len);
let pos = pos as usize;
let len = len as usize;
let result_slice = if pos + len < contig.len() {
&contig[pos..pos + len]
} else {
&contig[pos..]
};
let mut result = result_slice.to_vec();
let result_ptr = result.as_mut_ptr();
let result_len = result.len();
std::mem::forget(result);
ContigSlice {
data: result_ptr,
len: result_len,
}
}
}
#[no_mangle]
pub extern "C" fn ragc_free_contig_slice(slice: ContigSlice) {
unsafe {
if !slice.data.is_null() && slice.len > 0 {
let _ = Vec::from_raw_parts(slice.data, slice.len, slice.len);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_part_full_length() {
let contig = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let slice = ragc_get_contig_part(contig.as_ptr(), contig.len(), 2, 5);
unsafe {
let result = slice::from_raw_parts(slice.data, slice.len);
assert_eq!(result, &[2, 3, 4, 5, 6]);
}
ragc_free_contig_slice(slice);
}
#[test]
fn test_get_part_exceeds_length() {
let contig = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let slice = ragc_get_contig_part(contig.as_ptr(), contig.len(), 7, 10);
unsafe {
let result = slice::from_raw_parts(slice.data, slice.len);
assert_eq!(result, &[7, 8, 9]);
}
ragc_free_contig_slice(slice);
}
#[test]
fn test_get_part_exact_end() {
let contig = vec![0, 1, 2, 3, 4];
let slice = ragc_get_contig_part(contig.as_ptr(), contig.len(), 2, 3);
unsafe {
let result = slice::from_raw_parts(slice.data, slice.len);
assert_eq!(result, &[2, 3, 4]);
}
ragc_free_contig_slice(slice);
}
}