Skip to content

Commit 19bb96b

Browse files
committed
Manually implementing From for SliceOrIndex
1 parent 81b942f commit 19bb96b

File tree

1 file changed

+152
-50
lines changed

1 file changed

+152
-50
lines changed

src/hl/selection.rs

+152-50
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::borrow::Cow;
2+
use std::convert::{TryFrom, TryInto};
23
use std::fmt::{self, Display};
34
use std::mem;
45
use std::ops::{Deref, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
@@ -267,19 +268,148 @@ impl SliceOrIndex {
267268
}
268269
}
269270

270-
#[allow(clippy::fallible_impl_from)]
271-
impl<T: Into<ndarray::SliceInfoElem>> From<T> for SliceOrIndex {
272-
fn from(slice: T) -> Self {
273-
match slice.into() {
271+
impl TryFrom<ndarray::SliceInfoElem> for SliceOrIndex {
272+
type Error = Error;
273+
fn try_from(slice: ndarray::SliceInfoElem) -> Result<Self, Self::Error> {
274+
Ok(match slice.into() {
274275
ndarray::SliceInfoElem::Index(index) => Self::Index(index),
275276
ndarray::SliceInfoElem::Slice { start, end, step } => {
276277
Self::Slice { start, step, end, block: false }
277278
}
278-
ndarray::SliceInfoElem::NewAxis => panic!("ndarray NewAxis can not be mapped to hdf5"),
279-
}
279+
ndarray::SliceInfoElem::NewAxis => fail!("ndarray NewAxis can not be mapped to hdf5"),
280+
})
280281
}
281282
}
282283

284+
macro_rules! impl_slice_or_index_scalar {
285+
($tp:ty) => {
286+
impl From<$tp> for SliceOrIndex {
287+
fn from(val: $tp) -> Self {
288+
Self::Index(val as _)
289+
}
290+
}
291+
292+
impl From<$tp> for Hyperslab {
293+
fn from(slice: $tp) -> Self {
294+
(slice,).into()
295+
}
296+
}
297+
298+
impl From<$tp> for Selection {
299+
fn from(slice: $tp) -> Self {
300+
Hyperslab::from(slice).into()
301+
}
302+
}
303+
};
304+
}
305+
306+
impl_slice_or_index_scalar!(usize);
307+
impl_slice_or_index_scalar!(isize);
308+
impl_slice_or_index_scalar!(i32);
309+
310+
macro_rules! impl_slice_or_index_ranges {
311+
($tp:ty) => {
312+
impl From<Range<$tp>> for SliceOrIndex {
313+
fn from(val: Range<$tp>) -> Self {
314+
Self::Slice { start: 0, step: 1, end: Some(val.end as _), block: false }
315+
}
316+
}
317+
318+
impl From<Range<$tp>> for Hyperslab {
319+
fn from(val: Range<$tp>) -> Self {
320+
vec![val.into()].into()
321+
}
322+
}
323+
324+
impl From<Range<$tp>> for Selection {
325+
fn from(val: Range<$tp>) -> Self {
326+
Hyperslab::from(val).into()
327+
}
328+
}
329+
330+
impl From<RangeToInclusive<$tp>> for SliceOrIndex {
331+
fn from(val: RangeToInclusive<$tp>) -> Self {
332+
Self::Slice { start: 0, step: 1, end: Some(val.end as isize + 1), block: false }
333+
}
334+
}
335+
336+
impl From<RangeToInclusive<$tp>> for Hyperslab {
337+
fn from(val: RangeToInclusive<$tp>) -> Self {
338+
vec![val.into()].into()
339+
}
340+
}
341+
342+
impl From<RangeToInclusive<$tp>> for Selection {
343+
fn from(val: RangeToInclusive<$tp>) -> Self {
344+
Hyperslab::from(val).into()
345+
}
346+
}
347+
348+
impl From<RangeFrom<$tp>> for SliceOrIndex {
349+
fn from(val: RangeFrom<$tp>) -> Self {
350+
Self::Slice { start: val.start as _, step: 1, end: None, block: false }
351+
}
352+
}
353+
354+
impl From<RangeFrom<$tp>> for Hyperslab {
355+
fn from(val: RangeFrom<$tp>) -> Self {
356+
vec![val.into()].into()
357+
}
358+
}
359+
360+
impl From<RangeFrom<$tp>> for Selection {
361+
fn from(val: RangeFrom<$tp>) -> Self {
362+
Hyperslab::from(val).into()
363+
}
364+
}
365+
366+
impl From<RangeInclusive<$tp>> for SliceOrIndex {
367+
fn from(val: RangeInclusive<$tp>) -> Self {
368+
Self::Slice {
369+
start: *val.start() as _,
370+
step: 1,
371+
end: Some(*val.end() as isize + 1),
372+
block: false,
373+
}
374+
}
375+
}
376+
377+
impl From<RangeInclusive<$tp>> for Hyperslab {
378+
fn from(val: RangeInclusive<$tp>) -> Self {
379+
vec![val.into()].into()
380+
}
381+
}
382+
383+
impl From<RangeInclusive<$tp>> for Selection {
384+
fn from(val: RangeInclusive<$tp>) -> Self {
385+
Hyperslab::from(val).into()
386+
}
387+
}
388+
389+
impl From<RangeTo<$tp>> for SliceOrIndex {
390+
fn from(val: RangeTo<$tp>) -> Self {
391+
Self::Slice { start: 0, step: 1, end: Some(val.end as _), block: false }
392+
}
393+
}
394+
395+
impl From<RangeTo<$tp>> for Hyperslab {
396+
fn from(val: RangeTo<$tp>) -> Self {
397+
vec![val.into()].into()
398+
}
399+
}
400+
401+
impl From<RangeTo<$tp>> for Selection {
402+
fn from(val: RangeTo<$tp>) -> Self {
403+
Hyperslab::from(val).into()
404+
}
405+
}
406+
};
407+
}
408+
409+
impl_slice_or_index_ranges!(usize);
410+
impl_slice_or_index_ranges!(isize);
411+
impl_slice_or_index_ranges!(i32);
412+
283413
impl Display for SliceOrIndex {
284414
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
285415
match *self {
@@ -441,14 +571,22 @@ impl From<SliceOrIndex> for Hyperslab {
441571
}
442572
}
443573

444-
impl<T, Din, Dout> From<ndarray::SliceInfo<T, Din, Dout>> for Hyperslab
574+
impl<T, Din, Dout> TryFrom<ndarray::SliceInfo<T, Din, Dout>> for Hyperslab
445575
where
446576
T: AsRef<[ndarray::SliceInfoElem]>,
447577
Din: ndarray::Dimension,
448578
Dout: ndarray::Dimension,
449579
{
450-
fn from(slice: ndarray::SliceInfo<T, Din, Dout>) -> Self {
451-
slice.deref().as_ref().iter().cloned().map(Into::into).collect::<Vec<_>>().into()
580+
type Error = Error;
581+
fn try_from(slice: ndarray::SliceInfo<T, Din, Dout>) -> Result<Self, Self::Error> {
582+
slice
583+
.deref()
584+
.as_ref()
585+
.iter()
586+
.cloned()
587+
.map(TryInto::try_into)
588+
.collect::<Result<Vec<_>>>()
589+
.map(Into::into)
452590
}
453591
}
454592

@@ -669,14 +807,15 @@ impl From<Hyperslab> for Selection {
669807
}
670808
}
671809

672-
impl<T, Din, Dout> From<ndarray::SliceInfo<T, Din, Dout>> for Selection
810+
impl<T, Din, Dout> TryFrom<ndarray::SliceInfo<T, Din, Dout>> for Selection
673811
where
674812
T: AsRef<[ndarray::SliceInfoElem]>,
675813
Din: ndarray::Dimension,
676814
Dout: ndarray::Dimension,
677815
{
678-
fn from(slice: ndarray::SliceInfo<T, Din, Dout>) -> Self {
679-
Hyperslab::from(slice).into()
816+
type Error = Error;
817+
fn try_from(slice: ndarray::SliceInfo<T, Din, Dout>) -> Result<Self, Self::Error> {
818+
Hyperslab::try_from(slice).map(Into::into)
680819
}
681820
}
682821

@@ -686,14 +825,13 @@ impl From<Array2<Ix>> for Selection {
686825
}
687826
}
688827

689-
#[allow(clippy::fallible_impl_from)]
690828
impl From<Array1<Ix>> for Selection {
691829
fn from(points: Array1<Ix>) -> Self {
692830
let n = points.len();
693831
Self::Points(if n == 0 {
694832
Array2::zeros((0, 0))
695833
} else {
696-
points.into_shape((n, 1)).unwrap().into_dimensionality().unwrap()
834+
points.insert_axis(ndarray::Axis(1))
697835
})
698836
}
699837
}
@@ -775,42 +913,6 @@ macro_rules! impl_tuple {
775913

776914
impl_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
777915

778-
macro_rules! impl_slice_scalar {
779-
($tp:ty) => {
780-
impl From<$tp> for Hyperslab {
781-
fn from(slice: $tp) -> Self {
782-
(slice,).into()
783-
}
784-
}
785-
786-
impl From<$tp> for Selection {
787-
fn from(slice: $tp) -> Self {
788-
Hyperslab::from(slice).into()
789-
}
790-
}
791-
};
792-
}
793-
794-
impl_slice_scalar!(isize);
795-
impl_slice_scalar!(usize);
796-
impl_slice_scalar!(i32);
797-
impl_slice_scalar!(ndarray::Slice);
798-
impl_slice_scalar!(ndarray::SliceInfoElem);
799-
800-
macro_rules! impl_range_scalar {
801-
($index:ty) => {
802-
impl_slice_scalar!(Range<$index>);
803-
impl_slice_scalar!(RangeFrom<$index>);
804-
impl_slice_scalar!(RangeInclusive<$index>);
805-
impl_slice_scalar!(RangeTo<$index>);
806-
impl_slice_scalar!(RangeToInclusive<$index>);
807-
};
808-
}
809-
810-
impl_range_scalar!(isize);
811-
impl_range_scalar!(usize);
812-
impl_range_scalar!(i32);
813-
814916
#[cfg(test)]
815917
mod test {
816918
use ndarray::{arr1, arr2, s, Array2};

0 commit comments

Comments
 (0)