Skip to content

refactor: move Drop details for TreeSequence to sys. #432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,7 @@ pub fn panic_on_tskit_error(code: i32) {
/// This function must allocate a C string, which may panic
/// if the system runs out of memory.
pub fn get_tskit_error_message(code: i32) -> String {
let c_str = unsafe { std::ffi::CStr::from_ptr(crate::bindings::tsk_strerror(code)) };
c_str
.to_str()
.expect("failed to convert c_str to &str")
.to_owned()
sys::get_tskit_error_message(code)
}

/// Given an instance of [``TskReturnValue``](crate::TskReturnValue),
Expand Down
63 changes: 61 additions & 2 deletions src/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ use bindings::tsk_site_table_t;
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum Error {
#[error("{}", 0)]
#[error("{}", *.0)]
Message(String),
#[error("{}", 0)]
#[error("{}", get_tskit_error_message(*.0))]
Code(i32),
}

Expand Down Expand Up @@ -150,6 +150,22 @@ impl LLTreeSeq {
pub fn num_samples(&self) -> bindings::tsk_size_t {
unsafe { bindings::tsk_treeseq_get_num_samples(self.as_ptr()) }
}

fn free(&mut self) -> Result<(), Error> {
match unsafe { bindings::tsk_treeseq_free(self.as_mut_ptr()) } {
code if code < 0 => Err(Error::Code(code)),
_ => Ok(()),
}
}
}

impl Drop for LLTreeSeq {
fn drop(&mut self) {
match self.free() {
Ok(_) => (),
Err(e) => panic!("{:?}", e),
}
}
}

fn tsk_column_access_detail<R: Into<bindings::tsk_id_t>, L: Into<bindings::tsk_size_t>, T: Copy>(
Expand Down Expand Up @@ -256,3 +272,46 @@ pub fn generate_slice_mut<'a, L: Into<bindings::tsk_size_t>, I, O>(
// SAFETY: pointer is not null, length comes from C API
unsafe { std::slice::from_raw_parts_mut(data.cast::<O>(), length.into() as usize) }
}

pub fn get_tskit_error_message(code: i32) -> String {
let c_str = unsafe { std::ffi::CStr::from_ptr(crate::bindings::tsk_strerror(code)) };
c_str
.to_str()
.expect("failed to convert c_str to &str")
.to_owned()
}

#[test]
fn test_error_message() {
fn foo() -> Result<(), Error> {
Err(Error::Message("foobar".to_owned()))
}

let msg = "foobar".to_owned();
match foo() {
Err(Error::Message(m)) => assert_eq!(m, msg),
_ => panic!("unexpected match"),
}
}

#[test]
fn test_error_code() {
fn foo() -> Result<(), Error> {
Err(Error::Code(-202))
}

match foo() {
Err(Error::Code(x)) => {
assert_eq!(x, -202);
}
_ => panic!("unexpected match"),
}

match foo() {
Err(e) => {
let m = format!("{}", e);
assert_eq!(&m, "Node out of bounds. (TSK_ERR_NODE_OUT_OF_BOUNDS)");
}
_ => panic!("unexpected match"),
}
}
7 changes: 0 additions & 7 deletions src/trees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,6 @@ pub struct TreeSequence {
unsafe impl Send for TreeSequence {}
unsafe impl Sync for TreeSequence {}

impl Drop for TreeSequence {
fn drop(&mut self) {
let rv = unsafe { ll_bindings::tsk_treeseq_free(self.as_mut_ptr()) };
assert_eq!(rv, 0);
}
}

impl TreeSequence {
/// Create a tree sequence from a [`TableCollection`].
/// In general, [`TableCollection::tree_sequence`] may be preferred.
Expand Down