Skip to content

Commit 8c08334

Browse files
authored
refactor: move Drop details for TreeSequence to sys. (#432)
* works via LLTreeSeq.free() * add tests of sys::Error
1 parent 8b9ccbe commit 8c08334

File tree

3 files changed

+62
-14
lines changed

3 files changed

+62
-14
lines changed

src/error.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,7 @@ pub fn panic_on_tskit_error(code: i32) {
100100
/// This function must allocate a C string, which may panic
101101
/// if the system runs out of memory.
102102
pub fn get_tskit_error_message(code: i32) -> String {
103-
let c_str = unsafe { std::ffi::CStr::from_ptr(crate::bindings::tsk_strerror(code)) };
104-
c_str
105-
.to_str()
106-
.expect("failed to convert c_str to &str")
107-
.to_owned()
103+
sys::get_tskit_error_message(code)
108104
}
109105

110106
/// Given an instance of [``TskReturnValue``](crate::TskReturnValue),

src/sys.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use bindings::tsk_site_table_t;
1515
#[non_exhaustive]
1616
#[derive(Error, Debug)]
1717
pub enum Error {
18-
#[error("{}", 0)]
18+
#[error("{}", *.0)]
1919
Message(String),
20-
#[error("{}", 0)]
20+
#[error("{}", get_tskit_error_message(*.0))]
2121
Code(i32),
2222
}
2323

@@ -150,6 +150,22 @@ impl LLTreeSeq {
150150
pub fn num_samples(&self) -> bindings::tsk_size_t {
151151
unsafe { bindings::tsk_treeseq_get_num_samples(self.as_ptr()) }
152152
}
153+
154+
fn free(&mut self) -> Result<(), Error> {
155+
match unsafe { bindings::tsk_treeseq_free(self.as_mut_ptr()) } {
156+
code if code < 0 => Err(Error::Code(code)),
157+
_ => Ok(()),
158+
}
159+
}
160+
}
161+
162+
impl Drop for LLTreeSeq {
163+
fn drop(&mut self) {
164+
match self.free() {
165+
Ok(_) => (),
166+
Err(e) => panic!("{:?}", e),
167+
}
168+
}
153169
}
154170

155171
fn tsk_column_access_detail<R: Into<bindings::tsk_id_t>, L: Into<bindings::tsk_size_t>, T: Copy>(
@@ -256,3 +272,46 @@ pub fn generate_slice_mut<'a, L: Into<bindings::tsk_size_t>, I, O>(
256272
// SAFETY: pointer is not null, length comes from C API
257273
unsafe { std::slice::from_raw_parts_mut(data.cast::<O>(), length.into() as usize) }
258274
}
275+
276+
pub fn get_tskit_error_message(code: i32) -> String {
277+
let c_str = unsafe { std::ffi::CStr::from_ptr(crate::bindings::tsk_strerror(code)) };
278+
c_str
279+
.to_str()
280+
.expect("failed to convert c_str to &str")
281+
.to_owned()
282+
}
283+
284+
#[test]
285+
fn test_error_message() {
286+
fn foo() -> Result<(), Error> {
287+
Err(Error::Message("foobar".to_owned()))
288+
}
289+
290+
let msg = "foobar".to_owned();
291+
match foo() {
292+
Err(Error::Message(m)) => assert_eq!(m, msg),
293+
_ => panic!("unexpected match"),
294+
}
295+
}
296+
297+
#[test]
298+
fn test_error_code() {
299+
fn foo() -> Result<(), Error> {
300+
Err(Error::Code(-202))
301+
}
302+
303+
match foo() {
304+
Err(Error::Code(x)) => {
305+
assert_eq!(x, -202);
306+
}
307+
_ => panic!("unexpected match"),
308+
}
309+
310+
match foo() {
311+
Err(e) => {
312+
let m = format!("{}", e);
313+
assert_eq!(&m, "Node out of bounds. (TSK_ERR_NODE_OUT_OF_BOUNDS)");
314+
}
315+
_ => panic!("unexpected match"),
316+
}
317+
}

src/trees.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,6 @@ pub struct TreeSequence {
191191
unsafe impl Send for TreeSequence {}
192192
unsafe impl Sync for TreeSequence {}
193193

194-
impl Drop for TreeSequence {
195-
fn drop(&mut self) {
196-
let rv = unsafe { ll_bindings::tsk_treeseq_free(self.as_mut_ptr()) };
197-
assert_eq!(rv, 0);
198-
}
199-
}
200-
201194
impl TreeSequence {
202195
/// Create a tree sequence from a [`TableCollection`].
203196
/// In general, [`TableCollection::tree_sequence`] may be preferred.

0 commit comments

Comments
 (0)