Skip to content

Commit 4d44d22

Browse files
authored
Merge pull request #51 from aldanor/no-error-chain
Remove error-chain dependency + various cleanups
2 parents c4f873b + 978c3db commit 4d44d22

File tree

20 files changed

+147
-127
lines changed

20 files changed

+147
-127
lines changed

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
- `File::open(path, "r")` is now `File::open(path)`
1515
- `File::open(path, "r+")` is now `File::open_rw(path)`
1616
- `File::open(path, "w")` is now `File::create(path)`
17-
- `File::open(path, "x" | "w-")` is now `File::create_exl(path)`
17+
- `File::open(path, "x" | "w-")` is now `File::create_excl(path)`
1818
- `File::open(path, "a")` is now `File::append(path)`
1919
- Also added `File::open_as(path, mode)` which accepts the mode enum.
2020
- Rewritten `FileBuilder`: it no longer accepts userblock, driver etc;
@@ -33,6 +33,14 @@
3333
- It's no longer prohibited to set FCPL options when opening a file
3434
and not creating it -- it will simply be silently ignored (this
3535
simplifies the behavior and allows using a single file builder).
36+
- Added an explicit `hdf5_types::string::StringError` error type,
37+
as a result `error-chain` dependency has been dropped.
38+
- `hdf5::Error` is now convertible from `ndarray::ShapeError`;
39+
`hdf5::ResultExt` trait has been removed.
40+
41+
### Fixed
42+
43+
- Replaced deprecated `std::mem::uninitialized` with `std::mem::MaybeUninit`.
3644

3745
## 0.5.2
3846

hdf5-types/Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,3 @@ libc = "0.2"
1515

1616
[dev-dependencies]
1717
quickcheck = "0.8"
18-
19-
[dependencies.error-chain]
20-
version = "0.12"
21-
default-features = false

hdf5-types/src/error.rs

Lines changed: 0 additions & 2 deletions
This file was deleted.

hdf5-types/src/lib.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#![recursion_limit = "1024"]
22
#![cfg_attr(feature = "cargo-clippy", allow(clippy::transmute_bytes_to_str))]
33

4-
#[macro_use]
5-
extern crate error_chain;
6-
74
#[cfg(test)]
85
#[macro_use]
96
extern crate quickcheck;
@@ -12,17 +9,8 @@ mod array;
129
mod h5type;
1310
mod string;
1411

15-
mod errors {
16-
error_chain! {
17-
foreign_links {
18-
Ascii(::ascii::AsAsciiStrError);
19-
}
20-
}
21-
}
22-
2312
pub use self::array::{Array, VarLenArray};
24-
pub use self::errors::Error;
2513
pub use self::h5type::{
2614
CompoundField, CompoundType, EnumMember, EnumType, FloatSize, H5Type, IntSize, TypeDescriptor,
2715
};
28-
pub use self::string::{FixedAscii, FixedUnicode, VarLenAscii, VarLenUnicode};
16+
pub use self::string::{FixedAscii, FixedUnicode, StringError, VarLenAscii, VarLenUnicode};

hdf5-types/src/string.rs

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::borrow::{Borrow, Cow};
2+
use std::error::Error as StdError;
23
use std::fmt;
34
use std::hash::{Hash, Hasher};
45
use std::mem;
@@ -10,7 +11,38 @@ use std::str::{self, FromStr};
1011
use ascii::{AsAsciiStr, AsAsciiStrError, AsciiStr};
1112

1213
use crate::array::Array;
13-
use crate::errors::Result;
14+
15+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
16+
pub enum StringError {
17+
InternalNull,
18+
InsufficientCapacity,
19+
AsciiError(AsAsciiStrError),
20+
#[doc(hidden)]
21+
__Incomplete,
22+
}
23+
24+
impl From<AsAsciiStrError> for StringError {
25+
fn from(err: AsAsciiStrError) -> Self {
26+
StringError::AsciiError(err)
27+
}
28+
}
29+
30+
impl StdError for StringError {
31+
fn description(&self) -> &str {
32+
match self {
33+
StringError::InternalNull => "variable length string with internal null",
34+
StringError::InsufficientCapacity => "insufficient capacity for fixed sized string",
35+
StringError::AsciiError(err) => err.description(),
36+
_ => "",
37+
}
38+
}
39+
}
40+
41+
impl fmt::Display for StringError {
42+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
43+
write!(f, "string error: {}", self.description())
44+
}
45+
}
1446

1547
// ================================================================================
1648

@@ -221,12 +253,10 @@ impl VarLenAscii {
221253
Self::from_bytes(bytes.as_ref())
222254
}
223255

224-
pub fn from_ascii<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> Result<Self> {
256+
pub fn from_ascii<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> Result<Self, StringError> {
225257
let bytes = bytes.as_ref();
226258
if !bytes.iter().all(|&c| c != 0) {
227-
bail!("Variable length ASCII string with internal null: {:?}", unsafe {
228-
str::from_utf8_unchecked(bytes)
229-
});
259+
return Err(StringError::InternalNull);
230260
}
231261
let s = AsciiStr::from_ascii(bytes)?;
232262
unsafe { Ok(Self::from_bytes(s.as_bytes())) }
@@ -239,7 +269,7 @@ impl AsAsciiStr for VarLenAscii {
239269
AsciiStr::from_ascii_unchecked(self.as_bytes())
240270
}
241271

242-
fn as_ascii_str(&self) -> ::std::result::Result<&AsciiStr, AsAsciiStrError> {
272+
fn as_ascii_str(&self) -> Result<&AsciiStr, AsAsciiStrError> {
243273
AsciiStr::from_ascii(self.as_bytes())
244274
}
245275
}
@@ -322,11 +352,14 @@ impl VarLenUnicode {
322352
}
323353

324354
impl FromStr for VarLenUnicode {
325-
type Err = crate::errors::Error;
355+
type Err = StringError;
326356

327-
fn from_str(s: &str) -> Result<Self> {
328-
ensure!(s.chars().all(|c| c != '\0'), "Variable length unicode string with internal null");
329-
unsafe { Ok(Self::from_bytes(s.as_bytes())) }
357+
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
358+
if s.chars().all(|c| c != '\0') {
359+
unsafe { Ok(Self::from_bytes(s.as_bytes())) }
360+
} else {
361+
Err(StringError::InternalNull)
362+
}
330363
}
331364
}
332365

@@ -342,9 +375,9 @@ impl<A: Array<Item = u8>> Clone for FixedAscii<A> {
342375
#[inline]
343376
fn clone(&self) -> Self {
344377
unsafe {
345-
let mut buf: A = mem::uninitialized();
346-
ptr::copy_nonoverlapping(self.buf.as_ptr(), buf.as_mut_ptr(), A::capacity());
347-
FixedAscii { buf }
378+
let mut buf = mem::MaybeUninit::<A>::uninit();
379+
ptr::copy_nonoverlapping(self.buf.as_ptr(), buf.as_mut_ptr() as *mut _, A::capacity());
380+
FixedAscii { buf: buf.assume_init() }
348381
}
349382
}
350383
}
@@ -403,12 +436,12 @@ impl<A: Array<Item = u8>> FixedAscii<A> {
403436
Self::from_bytes(bytes.as_ref())
404437
}
405438

406-
pub fn from_ascii<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> Result<Self> {
439+
pub fn from_ascii<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> Result<Self, StringError> {
407440
let bytes = bytes.as_ref();
408-
ensure!(bytes.len() <= A::capacity(), "Insufficient capacity for fixed-size ASCII string");
409-
let s = AsciiStr::from_ascii(bytes).map_err(|_| {
410-
format!("Invalid ASCII string: `{}`", unsafe { str::from_utf8_unchecked(bytes) })
411-
})?;
441+
if bytes.len() > A::capacity() {
442+
return Err(StringError::InsufficientCapacity);
443+
}
444+
let s = AsciiStr::from_ascii(bytes)?;
412445
unsafe { Ok(Self::from_bytes(s.as_bytes())) }
413446
}
414447
}
@@ -419,7 +452,7 @@ impl<A: Array<Item = u8>> AsAsciiStr for FixedAscii<A> {
419452
AsciiStr::from_ascii_unchecked(self.as_bytes())
420453
}
421454

422-
fn as_ascii_str(&self) -> ::std::result::Result<&AsciiStr, AsAsciiStrError> {
455+
fn as_ascii_str(&self) -> Result<&AsciiStr, AsAsciiStrError> {
423456
AsciiStr::from_ascii(self.as_bytes())
424457
}
425458
}
@@ -436,9 +469,9 @@ impl<A: Array<Item = u8>> Clone for FixedUnicode<A> {
436469
#[inline]
437470
fn clone(&self) -> Self {
438471
unsafe {
439-
let mut buf: A = mem::uninitialized();
440-
ptr::copy_nonoverlapping(self.buf.as_ptr(), buf.as_mut_ptr(), A::capacity());
441-
FixedUnicode { buf }
472+
let mut buf = mem::MaybeUninit::<A>::uninit();
473+
ptr::copy_nonoverlapping(self.buf.as_ptr(), buf.as_mut_ptr() as *mut _, A::capacity());
474+
FixedUnicode { buf: buf.assume_init() }
442475
}
443476
}
444477
}
@@ -507,14 +540,14 @@ impl<A> FromStr for FixedUnicode<A>
507540
where
508541
A: Array<Item = u8>,
509542
{
510-
type Err = crate::errors::Error;
543+
type Err = StringError;
511544

512-
fn from_str(s: &str) -> Result<Self> {
513-
ensure!(
514-
s.as_bytes().len() <= A::capacity(),
515-
"Insufficient capacity for fixed-size unicode string"
516-
);
517-
unsafe { Ok(Self::from_bytes(s.as_bytes())) }
545+
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
546+
if s.as_bytes().len() <= A::capacity() {
547+
unsafe { Ok(Self::from_bytes(s.as_bytes())) }
548+
} else {
549+
Err(StringError::InsufficientCapacity)
550+
}
518551
}
519552
}
520553

src/error.rs

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use std::cell::RefCell;
2+
use std::error::Error as StdError;
23
use std::fmt;
34
use std::ops::Index;
45
use std::ptr;
56

67
use lazy_static::lazy_static;
8+
use ndarray::ShapeError;
79
use num_integer::Integer;
810
use num_traits::{Bounded, Zero};
911
use parking_lot::Mutex;
@@ -52,6 +54,12 @@ impl ErrorFrame {
5254
#[doc(hidden)]
5355
pub struct SilenceErrors;
5456

57+
impl Default for SilenceErrors {
58+
fn default() -> Self {
59+
Self::new()
60+
}
61+
}
62+
5563
lazy_static! {
5664
static ref ERROR_HANDLER: Mutex<RefCell<usize>> = Mutex::default();
5765
}
@@ -63,7 +71,7 @@ extern "C" fn default_error_handler(estack: hid_t, _cdata: *mut c_void) -> herr_
6371
impl SilenceErrors {
6472
pub fn new() -> Self {
6573
Self::silence(true);
66-
SilenceErrors
74+
Self
6775
}
6876

6977
fn silence(on: bool) {
@@ -140,13 +148,12 @@ impl ErrorStack {
140148
match closure(*err_desc) {
141149
Ok(frame) => {
142150
data.stack.push(frame);
143-
0
144151
}
145152
Err(err) => {
146153
data.err = Some(err);
147-
0
148154
}
149155
}
156+
0
150157
}
151158
}
152159

@@ -209,7 +216,7 @@ impl ErrorStack {
209216
}
210217

211218
pub fn detail(&self) -> Option<String> {
212-
self.top().and_then(|frame| frame.detail())
219+
self.top().and_then(ErrorFrame::detail)
213220
}
214221
}
215222

@@ -219,7 +226,7 @@ pub enum Error {
219226
/// An error occurred in the C API of the HDF5 library. Full error stack is captured.
220227
HDF5(ErrorStack),
221228
/// A user error occurred in the high-level Rust API (e.g., invalid user input).
222-
Internal(String), // TODO: add error kinds etc, handle errors properly
229+
Internal(String),
223230
}
224231

225232
/// A type for results generated by HDF5-related functions where the `Err` type is
@@ -243,15 +250,18 @@ impl Error {
243250
}
244251
}
245252

246-
impl<S> From<S> for Error
247-
where
248-
S: Into<String>,
249-
{
250-
fn from(desc: S) -> Self {
253+
impl From<&str> for Error {
254+
fn from(desc: &str) -> Self {
251255
Error::Internal(desc.into())
252256
}
253257
}
254258

259+
impl From<String> for Error {
260+
fn from(desc: String) -> Self {
261+
Error::Internal(desc)
262+
}
263+
}
264+
255265
impl fmt::Debug for Error {
256266
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
257267
match *self {
@@ -267,24 +277,15 @@ impl fmt::Display for Error {
267277
}
268278
}
269279

270-
impl ::std::error::Error for Error {
280+
impl StdError for Error {
271281
fn description(&self) -> &str {
272282
self.description()
273283
}
274284
}
275285

276-
// TODO: this is a temporary shim
277-
#[doc(hidden)]
278-
pub trait ResultExt<T, E> {
279-
fn str_err(self) -> Result<T>;
280-
}
281-
282-
impl<T, E> ResultExt<T, E> for ::std::result::Result<T, E>
283-
where
284-
E: ::std::error::Error,
285-
{
286-
fn str_err(self) -> Result<T> {
287-
self.map_err(|e| Error::from(e.description()))
286+
impl From<ShapeError> for Error {
287+
fn from(err: ShapeError) -> Self {
288+
format!("shape error: {}", err.description()).into()
288289
}
289290
}
290291

src/hl/container.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ impl<'a> Reader<'a> {
133133

134134
self.read_into_buf(vec.as_mut_ptr(), Some(&fspace), Some(&mspace))?;
135135

136-
let arr = ArrayD::from_shape_vec(reduced_shape, vec).str_err()?;
137-
arr.into_dimensionality().str_err()
136+
let arr = ArrayD::from_shape_vec(reduced_shape, vec)?;
137+
Ok(arr.into_dimensionality()?)
138138
}
139139
}
140140

@@ -149,8 +149,8 @@ impl<'a> Reader<'a> {
149149
ensure!(obj_ndim == ndim, "ndim mismatch: expected {}, got {}", ndim, obj_ndim);
150150
}
151151
let vec = self.read_raw()?;
152-
let arr = ArrayD::from_shape_vec(shape, vec).str_err()?;
153-
arr.into_dimensionality().str_err()
152+
let arr = ArrayD::from_shape_vec(shape, vec)?;
153+
Ok(arr.into_dimensionality()?)
154154
}
155155

156156
/// Reads a dataset/attribute into a vector in memory order.
@@ -206,8 +206,8 @@ impl<'a> Reader<'a> {
206206
pub fn read_scalar<T: H5Type>(&self) -> Result<T> {
207207
let obj_ndim = self.obj.get_shape()?.ndim();
208208
ensure!(obj_ndim == 0, "ndim mismatch: expected scalar, got {}", obj_ndim);
209-
let mut val: T = unsafe { mem::uninitialized() };
210-
self.read_into_buf(&mut val as *mut _, None, None).map(|_| val)
209+
let mut val = mem::MaybeUninit::<T>::uninit();
210+
self.read_into_buf(val.as_mut_ptr(), None, None).map(|_| unsafe { val.assume_init() })
211211
}
212212
}
213213

@@ -394,7 +394,7 @@ impl ObjectClass for Container {
394394
const VALID_TYPES: &'static [H5I_type_t] = &[H5I_DATASET, H5I_ATTR];
395395

396396
fn from_handle(handle: Handle) -> Self {
397-
Container(handle)
397+
Self(handle)
398398
}
399399

400400
fn handle(&self) -> &Handle {

0 commit comments

Comments
 (0)