Skip to content

Commit 5f7b0d0

Browse files
committed
Use failure
1 parent c19c0e8 commit 5f7b0d0

File tree

5 files changed

+97
-60
lines changed

5 files changed

+97
-60
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ rand = "0.3.9"
1414

1515
[dependencies]
1616
num-traits = "0.2"
17+
failure = "0.1.3"
1718

1819
[dependencies.serde]
1920
version = "1.0"

src/error.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use failure::{Backtrace, Context, Fail};
2+
use std::fmt::{self, Display};
3+
4+
#[derive(Debug)]
5+
pub struct Error {
6+
inner: Context<ErrorKind>,
7+
}
8+
9+
#[derive(Debug, PartialEq, Fail)]
10+
pub enum ErrorKind {
11+
#[fail(display = "wrong dimension")]
12+
WrongDimension,
13+
#[fail(display = "non-finite coordinate")]
14+
NonFiniteCoordinate,
15+
#[fail(display = "zero capacity")]
16+
ZeroCapacity,
17+
}
18+
19+
impl Fail for Error {
20+
fn cause(&self) -> Option<&Fail> {
21+
self.inner.cause()
22+
}
23+
24+
fn backtrace(&self) -> Option<&Backtrace> {
25+
self.inner.backtrace()
26+
}
27+
}
28+
29+
impl Display for Error {
30+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31+
Display::fmt(&self.inner, f)
32+
}
33+
}
34+
35+
impl Error {
36+
pub fn new(inner: Context<ErrorKind>) -> Error {
37+
Error { inner }
38+
}
39+
40+
pub fn kind(&self) -> &ErrorKind {
41+
self.inner.get_context()
42+
}
43+
}
44+
45+
impl From<ErrorKind> for Error {
46+
fn from(kind: ErrorKind) -> Error {
47+
Error {
48+
inner: Context::new(kind),
49+
}
50+
}
51+
}
52+
53+
impl From<Context<ErrorKind>> for Error {
54+
fn from(inner: Context<ErrorKind>) -> Error {
55+
Error { inner }
56+
}
57+
}

src/kdtree.rs

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::BinaryHeap;
22

33
use num_traits::{Float, One, Zero};
44

5+
use crate::error::{Error, ErrorKind};
56
use crate::heap_element::HeapElement;
67
use crate::util;
78

@@ -25,14 +26,7 @@ pub struct KdTree<A, T, U: AsRef<[A]>> {
2526
bucket: Option<Vec<T>>,
2627
}
2728

28-
#[derive(Debug, PartialEq)]
29-
pub enum ErrorKind {
30-
WrongDimension,
31-
NonFiniteCoordinate,
32-
ZeroCapacity,
33-
}
34-
35-
impl<A: Float + Zero + One, T, U: AsRef<[A]>> KdTree<A, T, U> {
29+
impl<A: Float + Zero + One + Zero + One, T, U: AsRef<[A]>> KdTree<A, T, U> {
3630
pub fn new(dims: usize) -> Self {
3731
KdTree::new_with_capacity(dims, 2usize.pow(4))
3832
}
@@ -59,12 +53,7 @@ impl<A: Float + Zero + One, T, U: AsRef<[A]>> KdTree<A, T, U> {
5953
self.size
6054
}
6155

62-
pub fn nearest<F>(
63-
&self,
64-
point: &[A],
65-
num: usize,
66-
distance: &F,
67-
) -> Result<Vec<(A, &T)>, ErrorKind>
56+
pub fn nearest<F>(&self, point: &[A], num: usize, distance: &F) -> Result<Vec<(A, &T)>, Error>
6857
where
6958
F: Fn(&[A], &[A]) -> A,
7059
{
@@ -102,7 +91,7 @@ impl<A: Float + Zero + One, T, U: AsRef<[A]>> KdTree<A, T, U> {
10291
.collect())
10392
}
10493

105-
pub fn within<F>(&self, point: &[A], ridius: A, distance: &F) -> Result<Vec<(A, &T)>, ErrorKind>
94+
pub fn within<F>(&self, point: &[A], ridius: A, distance: &F) -> Result<Vec<(A, &T)>, Error>
10695
where
10796
F: Fn(&[A], &[A]) -> A,
10897
{
@@ -202,7 +191,7 @@ impl<A: Float + Zero + One, T, U: AsRef<[A]>> KdTree<A, T, U> {
202191
&'b self,
203192
point: &'a [A],
204193
distance: &'a F,
205-
) -> Result<NearestIter<'a, 'b, A, T, U, F>, ErrorKind>
194+
) -> Result<NearestIter<'a, 'b, A, T, U, F>, Error>
206195
where
207196
F: Fn(&[A], &[A]) -> A,
208197
{
@@ -223,17 +212,17 @@ impl<A: Float + Zero + One, T, U: AsRef<[A]>> KdTree<A, T, U> {
223212
})
224213
}
225214

226-
pub fn add(&mut self, point: U, data: T) -> Result<(), ErrorKind> {
215+
pub fn add(&mut self, point: U, data: T) -> Result<(), Error> {
227216
if self.capacity == 0 {
228-
return Err(ErrorKind::ZeroCapacity);
217+
Err(ErrorKind::ZeroCapacity)?;
229218
}
230219
if let Err(err) = self.check_point(point.as_ref()) {
231-
return Err(err);
220+
Err(err)?;
232221
}
233222
self.add_unchecked(point, data)
234223
}
235224

236-
fn add_unchecked(&mut self, point: U, data: T) -> Result<(), ErrorKind> {
225+
fn add_unchecked(&mut self, point: U, data: T) -> Result<(), Error> {
237226
if self.is_leaf() {
238227
self.add_to_bucket(point, data);
239228
return Ok(());
@@ -325,13 +314,13 @@ impl<A: Float + Zero + One, T, U: AsRef<[A]>> KdTree<A, T, U> {
325314
&& self.right.is_none()
326315
}
327316

328-
fn check_point(&self, point: &[A]) -> Result<(), ErrorKind> {
317+
fn check_point(&self, point: &[A]) -> Result<(), Error> {
329318
if self.dimensions != point.len() {
330-
return Err(ErrorKind::WrongDimension);
319+
Err(ErrorKind::WrongDimension)?;
331320
}
332321
for n in point {
333322
if !n.is_finite() {
334-
return Err(ErrorKind::NonFiniteCoordinate);
323+
Err(ErrorKind::NonFiniteCoordinate)?;
335324
}
336325
}
337326
Ok(())
@@ -399,23 +388,6 @@ where
399388
}
400389
}
401390

402-
impl std::error::Error for ErrorKind {
403-
fn description(&self) -> &str {
404-
match *self {
405-
ErrorKind::WrongDimension => "wrong dimension",
406-
ErrorKind::NonFiniteCoordinate => "non-finite coordinate",
407-
ErrorKind::ZeroCapacity => "zero capacity",
408-
}
409-
}
410-
}
411-
412-
impl std::fmt::Display for ErrorKind {
413-
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
414-
use std::error::Error;
415-
write!(f, "KdTree error: {}", self.description())
416-
}
417-
}
418-
419391
#[cfg(test)]
420392
mod tests {
421393
extern crate rand;

src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,18 @@
5353
//! );
5454
//! ```
5555
56+
#[macro_use]
57+
extern crate failure;
5658
extern crate num_traits;
57-
5859
#[cfg(feature = "serialize")]
5960
#[cfg_attr(feature = "serialize", macro_use)]
6061
extern crate serde_derive;
6162

6263
pub mod distance;
64+
mod error;
6365
mod heap_element;
6466
pub mod kdtree;
6567
mod util;
66-
pub use crate::kdtree::ErrorKind;
68+
69+
pub use crate::error::{Error, ErrorKind};
6770
pub use crate::kdtree::KdTree;

tests/kdtree.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,18 @@ fn it_works_with_vec() {
114114
);
115115
}
116116

117+
macro_rules! assert_err_kind {
118+
($expr: expr, $err: expr) => {{
119+
let err = $expr.unwrap_err();
120+
assert_eq!(*err.kind(), $err);
121+
}};
122+
}
123+
117124
#[test]
118125
fn handles_zero_capacity() {
119126
let mut kdtree = KdTree::new_with_capacity(2, 0);
120-
assert_eq!(
121-
kdtree.add(&POINT_A.0, POINT_A.1),
122-
Err(ErrorKind::ZeroCapacity)
123-
);
127+
128+
assert_err_kind!(kdtree.add(&POINT_A.0, POINT_A.1), ErrorKind::ZeroCapacity);
124129
assert_eq!(
125130
kdtree.nearest(&POINT_A.0, 1, &squared_euclidean).unwrap(),
126131
vec![]
@@ -131,13 +136,11 @@ fn handles_zero_capacity() {
131136
fn handles_wrong_dimension() {
132137
let point = ([0f64], 0f64);
133138
let mut kdtree = KdTree::new_with_capacity(2, 1);
134-
assert_eq!(
135-
kdtree.add(&point.0, point.1),
136-
Err(ErrorKind::WrongDimension)
137-
);
138-
assert_eq!(
139+
140+
assert_err_kind!(kdtree.add(&point.0, point.1), ErrorKind::WrongDimension);
141+
assert_err_kind!(
139142
kdtree.nearest(&point.0, 1, &squared_euclidean),
140-
Err(ErrorKind::WrongDimension)
143+
ErrorKind::WrongDimension
141144
);
142145
}
143146

@@ -146,21 +149,22 @@ fn handles_non_finite_coordinate() {
146149
let point_a = ([std::f64::NAN, std::f64::NAN], 0f64);
147150
let point_b = ([std::f64::INFINITY, std::f64::INFINITY], 0f64);
148151
let mut kdtree = KdTree::new_with_capacity(2, 1);
149-
assert_eq!(
152+
153+
assert_err_kind!(
150154
kdtree.add(&point_a.0, point_a.1),
151-
Err(ErrorKind::NonFiniteCoordinate)
155+
ErrorKind::NonFiniteCoordinate
152156
);
153-
assert_eq!(
157+
assert_err_kind!(
154158
kdtree.add(&point_b.0, point_b.1),
155-
Err(ErrorKind::NonFiniteCoordinate)
159+
ErrorKind::NonFiniteCoordinate
156160
);
157-
assert_eq!(
161+
assert_err_kind!(
158162
kdtree.nearest(&point_a.0, 1, &squared_euclidean),
159-
Err(ErrorKind::NonFiniteCoordinate)
163+
ErrorKind::NonFiniteCoordinate
160164
);
161-
assert_eq!(
165+
assert_err_kind!(
162166
kdtree.nearest(&point_b.0, 1, &squared_euclidean),
163-
Err(ErrorKind::NonFiniteCoordinate)
167+
ErrorKind::NonFiniteCoordinate
164168
);
165169
}
166170

0 commit comments

Comments
 (0)