Skip to content

Commit 8b9ccbe

Browse files
authored
refactor: sys module no longer depends on TskitError (#431)
* sys now defines its own Error. * impl From<sys::Error> for TskitError
1 parent 2c93206 commit 8b9ccbe

File tree

3 files changed

+53
-23
lines changed

3 files changed

+53
-23
lines changed

src/error.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Error handling
22
3+
use crate::sys;
34
use crate::TskReturnValue;
45
use thiserror::Error;
56

@@ -36,6 +37,15 @@ pub enum TskitError {
3637
LibraryError(String),
3738
}
3839

40+
impl From<crate::sys::Error> for TskitError {
41+
fn from(error: sys::Error) -> Self {
42+
match error {
43+
sys::Error::Message(msg) => TskitError::LibraryError(msg),
44+
sys::Error::Code(code) => TskitError::ErrorCode { code },
45+
}
46+
}
47+
}
48+
3949
/// Takes the return code from a tskit
4050
/// function and panics if the code indicates
4151
/// an error. The error message is included

src/sys.rs

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1-
use crate::{bindings, TskitError};
1+
use std::ffi::CString;
2+
use std::ptr::NonNull;
3+
4+
use thiserror::Error;
5+
6+
use crate::bindings;
27
use bindings::tsk_edge_table_t;
38
use bindings::tsk_individual_table_t;
49
use bindings::tsk_migration_table_t;
510
use bindings::tsk_mutation_table_t;
611
use bindings::tsk_node_table_t;
712
use bindings::tsk_population_table_t;
813
use bindings::tsk_site_table_t;
9-
use std::ffi::CString;
10-
use std::ptr::NonNull;
14+
15+
#[non_exhaustive]
16+
#[derive(Error, Debug)]
17+
pub enum Error {
18+
#[error("{}", 0)]
19+
Message(String),
20+
#[error("{}", 0)]
21+
Code(i32),
22+
}
1123

1224
#[cfg(feature = "provenance")]
1325
use bindings::tsk_provenance_table_t;
@@ -19,10 +31,10 @@ macro_rules! basic_lltableref_impl {
1931
pub struct $lltable(NonNull<bindings::$tsktable>);
2032

2133
impl $lltable {
22-
pub fn new_from_table(table: *mut $tsktable) -> Result<Self, TskitError> {
34+
pub fn new_from_table(table: *mut $tsktable) -> Result<Self, Error> {
2335
let internal = NonNull::new(table).ok_or_else(|| {
2436
let msg = format!("null pointer to {}", stringify!($tsktable));
25-
TskitError::LibraryError(msg)
37+
Error::Message(msg)
2638
})?;
2739
Ok(Self(internal))
2840
}
@@ -55,12 +67,14 @@ impl LLTreeSeq {
5567
pub fn new(
5668
tables: *mut bindings::tsk_table_collection_t,
5769
flags: bindings::tsk_flags_t,
58-
) -> Result<Self, TskitError> {
70+
) -> Result<Self, Error> {
5971
let mut inner = std::mem::MaybeUninit::<bindings::tsk_treeseq_t>::uninit();
6072
let mut flags = flags;
6173
flags |= bindings::TSK_TAKE_OWNERSHIP;
62-
let rv = unsafe { bindings::tsk_treeseq_init(inner.as_mut_ptr(), tables, flags) };
63-
handle_tsk_return_value!(rv, Self(unsafe { inner.assume_init() }))
74+
match unsafe { bindings::tsk_treeseq_init(inner.as_mut_ptr(), tables, flags) } {
75+
code if code < 0 => Err(Error::Code(code)),
76+
_ => Ok(Self(unsafe { inner.assume_init() })),
77+
}
6478
}
6579

6680
pub fn as_ref(&self) -> &bindings::tsk_treeseq_t {
@@ -80,7 +94,7 @@ impl LLTreeSeq {
8094
samples: &[bindings::tsk_id_t],
8195
options: bindings::tsk_flags_t,
8296
idmap: *mut bindings::tsk_id_t,
83-
) -> Result<Self, TskitError> {
97+
) -> Result<Self, Error> {
8498
// The output is an UNINITIALIZED treeseq,
8599
// else we leak memory.
86100
let mut ts = std::mem::MaybeUninit::<bindings::tsk_treeseq_t>::uninit();
@@ -102,33 +116,35 @@ impl LLTreeSeq {
102116
// and tsk_treeseq_free uses safe methods
103117
// to clean up.
104118
unsafe { bindings::tsk_treeseq_free(ts.as_mut_ptr()) };
119+
Err(Error::Code(rv))
120+
} else {
121+
Ok(Self(init))
105122
}
106-
handle_tsk_return_value!(rv, Self(init))
107123
}
108124

109-
pub fn dump(
110-
&self,
111-
filename: CString,
112-
options: bindings::tsk_flags_t,
113-
) -> Result<i32, TskitError> {
125+
pub fn dump(&self, filename: CString, options: bindings::tsk_flags_t) -> Result<i32, Error> {
114126
// SAFETY: self pointer is not null
115-
let rv = unsafe { bindings::tsk_treeseq_dump(self.as_ptr(), filename.as_ptr(), options) };
116-
handle_tsk_return_value!(rv)
127+
match unsafe { bindings::tsk_treeseq_dump(self.as_ptr(), filename.as_ptr(), options) } {
128+
code if code < 0 => Err(Error::Code(code)),
129+
code => Ok(code),
130+
}
117131
}
118132

119133
pub fn num_trees(&self) -> bindings::tsk_size_t {
120134
// SAFETY: self pointer is not null
121135
unsafe { bindings::tsk_treeseq_get_num_trees(self.as_ptr()) }
122136
}
123137

124-
pub fn kc_distance(&self, other: &Self, lambda: f64) -> Result<f64, TskitError> {
138+
pub fn kc_distance(&self, other: &Self, lambda: f64) -> Result<f64, Error> {
125139
let mut kc: f64 = f64::NAN;
126140
let kcp: *mut f64 = &mut kc;
127141
// SAFETY: self pointer is not null
128-
let code = unsafe {
142+
match unsafe {
129143
bindings::tsk_treeseq_kc_distance(self.as_ptr(), other.as_ptr(), lambda, kcp)
130-
};
131-
handle_tsk_return_value!(code, kc)
144+
} {
145+
code if code < 0 => Err(Error::Code(code)),
146+
_ => Ok(kc),
147+
}
132148
}
133149

134150
pub fn num_samples(&self) -> bindings::tsk_size_t {

src/trees.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,9 @@ impl TreeSequence {
282282
let c_str = std::ffi::CString::new(filename).map_err(|_| {
283283
TskitError::LibraryError("call to ffi::Cstring::new failed".to_string())
284284
})?;
285-
self.inner.dump(c_str, options.into().bits())
285+
self.inner
286+
.dump(c_str, options.into().bits())
287+
.map_err(|e| e.into())
286288
}
287289

288290
/// Load from a file.
@@ -404,7 +406,9 @@ impl TreeSequence {
404406
/// * `lambda` specifies the relative weight of topology and branch length.
405407
/// See [`TreeInterface::kc_distance`] for more details.
406408
pub fn kc_distance(&self, other: &TreeSequence, lambda: f64) -> Result<f64, TskitError> {
407-
self.inner.kc_distance(&other.inner, lambda)
409+
self.inner
410+
.kc_distance(&other.inner, lambda)
411+
.map_err(|e| e.into())
408412
}
409413

410414
// FIXME: document

0 commit comments

Comments
 (0)