use libc::c_char;
use rubydex::model::document::Document;
use rubydex::model::graph::Graph;
use rubydex::offset::Offset;
use std::ffi::CString;
#[repr(C)]
#[derive(Debug, Clone)]
pub struct Location {
pub uri: *const c_char,
pub start_line: u32,
pub end_line: u32,
pub start_column: u32,
pub end_column: u32,
}
#[must_use]
pub(crate) fn create_location_for_uri_and_offset(graph: &Graph, document: &Document, offset: &Offset) -> *mut Location {
let line_index = document.line_index();
let start_pos = line_index.line_col(offset.start().into());
let end_pos = line_index.line_col(offset.end().into());
let loc = if let Some(wide_encoding) = graph.encoding().to_wide() {
let wide_start_pos = line_index.to_wide(wide_encoding, start_pos).unwrap();
let wide_end_pos = line_index.to_wide(wide_encoding, end_pos).unwrap();
Location {
uri: CString::new(document.uri()).unwrap().into_raw().cast_const(),
start_line: wide_start_pos.line,
end_line: wide_end_pos.line,
start_column: wide_start_pos.col,
end_column: wide_end_pos.col,
}
} else {
Location {
uri: CString::new(document.uri()).unwrap().into_raw().cast_const(),
start_line: start_pos.line,
end_line: end_pos.line,
start_column: start_pos.col,
end_column: end_pos.col,
}
};
Box::into_raw(Box::new(loc))
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rdx_location_free(ptr: *mut Location) {
if ptr.is_null() {
return;
}
unsafe {
let boxed = Box::from_raw(ptr);
if !boxed.uri.is_null() {
let _ = CString::from_raw(boxed.uri.cast_mut());
}
}
}