Skip to content

Commit 7f77e99

Browse files
committed
Implement MatMatcher as trait
1 parent 0997504 commit 7f77e99

File tree

2 files changed

+97
-81
lines changed

2 files changed

+97
-81
lines changed

src/manual/core/mat.rs

Lines changed: 76 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -26,71 +26,79 @@ unsafe fn convert_ptr_mut<'r, T>(r: *mut u8) -> &'r mut T {
2626
unsafe { &mut *(r.cast::<T>()) }
2727
}
2828

29-
#[inline]
30-
fn match_format<T: DataType>(mat_type: i32) -> Result<()> {
31-
let out_type = T::opencv_type();
32-
if mat_type == out_type {
33-
Ok(())
34-
} else {
35-
let mat_type = core::type_to_string(mat_type)?;
36-
let out_type = core::type_to_string(out_type)?;
37-
Err(Error::new(
38-
core::StsUnmatchedFormats,
39-
format!("Mat type is: {mat_type}, but requested type is: {out_type}"),
40-
))
41-
}
29+
trait MatMatcher {
30+
fn match_indices(&self, idx: &[i32]) -> Result<()>;
31+
fn match_total(&self, idx: i32) -> Result<()>;
32+
fn match_is_continuous(&self) -> Result<()>;
4233
}
4334

44-
fn match_indices(mat: &(impl MatTraitConst + ?Sized), idx: &[i32]) -> Result<()> {
45-
let mat_size = mat.mat_size();
46-
let size = &*mat_size;
47-
if size.len() != idx.len() {
48-
return Err(Error::new(
49-
core::StsUnmatchedSizes,
50-
format!(
51-
"Amount of Mat dimensions: {} doesn't match the amount of requested indices: {}",
52-
size.len(),
53-
idx.len()
54-
),
55-
));
56-
}
57-
if let Some((out_idx, (out_idx_val, out_size))) = idx
58-
.iter()
59-
.zip(size)
60-
.enumerate()
61-
.find(|(_, (idx_val, &size))| !(0..size).contains(idx_val))
62-
{
63-
Err(Error::new(
64-
core::StsOutOfRange,
65-
format!("Index: {out_idx_val} along dimension: {out_idx} out of bounds 0..{out_size}"),
66-
))
67-
} else {
68-
Ok(())
35+
impl<T: MatTraitConst + ?Sized> MatMatcher for T {
36+
fn match_indices(&self, idx: &[i32]) -> Result<()> {
37+
let mat_size = self.mat_size();
38+
let size = &*mat_size;
39+
if size.len() != idx.len() {
40+
return Err(Error::new(
41+
core::StsUnmatchedSizes,
42+
format!(
43+
"Amount of Mat dimensions: {} doesn't match the amount of requested indices: {}",
44+
size.len(),
45+
idx.len()
46+
),
47+
));
48+
}
49+
if let Some((out_idx, (out_idx_val, out_size))) = idx
50+
.iter()
51+
.zip(size)
52+
.enumerate()
53+
.find(|(_, (idx_val, &size))| !(0..size).contains(idx_val))
54+
{
55+
Err(Error::new(
56+
core::StsOutOfRange,
57+
format!("Index: {out_idx_val} along dimension: {out_idx} out of bounds 0..{out_size}"),
58+
))
59+
} else {
60+
Ok(())
61+
}
6962
}
70-
}
7163

72-
#[inline]
73-
fn match_total(mat: &(impl MatTraitConst + ?Sized), idx: i32) -> Result<()> {
74-
let size = mat.total();
75-
// safe because of the `0 <= idx` check
76-
if 0 <= idx && (idx as usize) < size {
77-
Ok(())
78-
} else {
79-
Err(Error::new(
80-
core::StsOutOfRange,
81-
format!("Index: {idx} out of bounds: 0..{size}"),
82-
))
64+
#[inline]
65+
fn match_total(&self, idx: i32) -> Result<()> {
66+
let size = self.total();
67+
// safe because of the `0 <= idx` check
68+
if 0 <= idx && (idx as usize) < size {
69+
Ok(())
70+
} else {
71+
Err(Error::new(
72+
core::StsOutOfRange,
73+
format!("Index: {idx} out of bounds: 0..{size}"),
74+
))
75+
}
76+
}
77+
78+
#[inline]
79+
fn match_is_continuous(&self) -> Result<()> {
80+
if self.is_continuous() {
81+
Ok(())
82+
} else {
83+
Err(Error::new(
84+
core::StsUnmatchedSizes,
85+
"Mat is not continuous, operation is not applicable",
86+
))
87+
}
8388
}
8489
}
8590

8691
#[inline]
87-
fn match_is_continuous(mat: &(impl MatTraitConst + ?Sized)) -> Result<()> {
88-
if mat.is_continuous() {
92+
fn match_format<T: DataType>(mat_type: i32) -> Result<()> {
93+
let out_type = T::opencv_type();
94+
if mat_type == out_type {
8995
Ok(())
9096
} else {
97+
let mat_type = core::type_to_string(mat_type)?;
98+
let out_type = core::type_to_string(out_type)?;
9199
Err(Error::new(
92-
core::StsUnmatchedSizes,
93-
"Mat is not continuous, operation is not applicable",
100+
core::StsUnmatchedFormats,
101+
format!("Mat type is: {mat_type}, but requested type is: {out_type}"),
94102
))
95103
}
96104
}
@@ -403,7 +411,7 @@ pub(crate) mod mat_forward {
403411
#[inline]
404412
pub fn at<T: DataType>(mat: &(impl MatTraitConst + ?Sized), i0: i32) -> Result<&T> {
405413
match_format::<T>(mat.typ())
406-
.and_then(|_| match_total(mat, i0))
414+
.and_then(|_| mat.match_total(i0))
407415
.and_then(|_| unsafe { mat.at_unchecked(i0) })
408416
}
409417

@@ -414,7 +422,7 @@ pub(crate) mod mat_forward {
414422

415423
#[inline]
416424
pub fn at_mut<T: DataType>(mat: &mut (impl MatTrait + ?Sized), i0: i32) -> Result<&mut T> {
417-
match_format::<T>(mat.typ()).and_then(|_| match_total(mat, i0))?;
425+
match_format::<T>(mat.typ()).and_then(|_| mat.match_total(i0))?;
418426
unsafe { mat.at_unchecked_mut(i0) }
419427
}
420428

@@ -426,13 +434,13 @@ pub(crate) mod mat_forward {
426434
#[inline]
427435
pub fn at_2d<T: DataType>(mat: &(impl MatTraitConst + ?Sized), row: i32, col: i32) -> Result<&T> {
428436
match_format::<T>(mat.typ())
429-
.and_then(|_| match_indices(mat, &[row, col]))
437+
.and_then(|_| mat.match_indices(&[row, col]))
430438
.and_then(|_| unsafe { mat.at_2d_unchecked(row, col) })
431439
}
432440

433441
#[inline]
434442
pub fn at_2d_mut<T: DataType>(mat: &mut (impl MatTrait + ?Sized), row: i32, col: i32) -> Result<&mut T> {
435-
match_format::<T>(mat.typ()).and_then(|_| match_indices(mat, &[row, col]))?;
443+
match_format::<T>(mat.typ()).and_then(|_| mat.match_indices(&[row, col]))?;
436444
unsafe { mat.at_2d_unchecked_mut(row, col) }
437445
}
438446

@@ -449,26 +457,26 @@ pub(crate) mod mat_forward {
449457
#[inline]
450458
pub fn at_3d<T: DataType>(mat: &(impl MatTraitConst + ?Sized), i0: i32, i1: i32, i2: i32) -> Result<&T> {
451459
match_format::<T>(mat.typ())
452-
.and_then(|_| match_indices(mat, &[i0, i1, i2]))
460+
.and_then(|_| mat.match_indices(&[i0, i1, i2]))
453461
.and_then(|_| unsafe { mat.at_3d_unchecked(i0, i1, i2) })
454462
}
455463

456464
#[inline]
457465
pub fn at_3d_mut<T: DataType>(mat: &mut (impl MatTrait + ?Sized), i0: i32, i1: i32, i2: i32) -> Result<&mut T> {
458-
match_format::<T>(mat.typ()).and_then(|_| match_indices(mat, &[i0, i1, i2]))?;
466+
match_format::<T>(mat.typ()).and_then(|_| mat.match_indices(&[i0, i1, i2]))?;
459467
unsafe { mat.at_3d_unchecked_mut(i0, i1, i2) }
460468
}
461469

462470
#[inline]
463471
pub fn at_nd<'s, T: DataType>(mat: &'s (impl MatTraitConst + ?Sized), idx: &[i32]) -> Result<&'s T> {
464472
match_format::<T>(mat.typ())
465-
.and_then(|_| match_indices(mat, idx))
473+
.and_then(|_| mat.match_indices(idx))
466474
.and_then(|_| unsafe { mat.at_nd_unchecked(idx) })
467475
}
468476

469477
#[inline]
470478
pub fn at_nd_mut<'s, T: DataType>(mat: &'s mut (impl MatTrait + ?Sized), idx: &[i32]) -> Result<&'s mut T> {
471-
match_format::<T>(mat.typ()).and_then(|_| match_indices(mat, idx))?;
479+
match_format::<T>(mat.typ()).and_then(|_| mat.match_indices(idx))?;
472480
unsafe { mat.at_nd_unchecked_mut(idx) }
473481
}
474482
}
@@ -519,7 +527,7 @@ pub trait MatTraitConstManual: MatTraitConst {
519527
#[inline]
520528
fn at_row<T: DataType>(&self, row: i32) -> Result<&[T]> {
521529
match_format::<T>(self.typ())
522-
.and_then(|_| match_indices(self, &[row, 0]))
530+
.and_then(|_| self.match_indices(&[row, 0]))
523531
.and_then(|_| unsafe { self.at_row_unchecked(row) })
524532
}
525533

@@ -547,7 +555,7 @@ pub trait MatTraitConstManual: MatTraitConst {
547555
/// Returns the underlying data array as a byte slice, [Mat] must be continuous
548556
#[inline]
549557
fn data_bytes(&self) -> Result<&[u8]> {
550-
match_is_continuous(self).and_then(|_| {
558+
self.match_is_continuous().and_then(|_| {
551559
let data = self.data();
552560
Ok(if data.is_null() {
553561
&[]
@@ -560,7 +568,7 @@ pub trait MatTraitConstManual: MatTraitConst {
560568
#[inline]
561569
fn data_typed<T: DataType>(&self) -> Result<&[T]> {
562570
match_format::<T>(self.typ())
563-
.and_then(|_| match_is_continuous(self))
571+
.and_then(|_| self.match_is_continuous())
564572
.and_then(|_| unsafe { self.data_typed_unchecked() })
565573
}
566574

@@ -686,7 +694,7 @@ pub trait MatTraitManual: MatTraitConstManual + MatTrait {
686694
/// Return a complete writeable row
687695
#[inline]
688696
fn at_row_mut<T: DataType>(&mut self, row: i32) -> Result<&mut [T]> {
689-
match_format::<T>(self.typ()).and_then(|_| match_indices(self, &[row, 0]))?;
697+
match_format::<T>(self.typ()).and_then(|_| self.match_indices(&[row, 0]))?;
690698
unsafe { self.at_row_unchecked_mut(row) }
691699
}
692700

@@ -709,7 +717,7 @@ pub trait MatTraitManual: MatTraitConstManual + MatTrait {
709717
/// Returns the underlying data array as a mutable byte slice, Mat must be continuous.
710718
#[inline]
711719
fn data_bytes_mut(&mut self) -> Result<&mut [u8]> {
712-
match_is_continuous(self).and_then(|_| {
720+
self.match_is_continuous().and_then(|_| {
713721
let data = self.data_mut();
714722
Ok(if data.is_null() {
715723
&mut []
@@ -721,7 +729,7 @@ pub trait MatTraitManual: MatTraitConstManual + MatTrait {
721729

722730
#[inline]
723731
fn data_typed_mut<T: DataType>(&mut self) -> Result<&mut [T]> {
724-
match_format::<T>(self.typ()).and_then(|_| match_is_continuous(self))?;
732+
match_format::<T>(self.typ()).and_then(|_| self.match_is_continuous())?;
725733
unsafe { self.data_typed_unchecked_mut() }
726734
}
727735

src/manual/core/mat/mat_.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::ffi::c_void;
33
use std::fmt;
44
use std::marker::PhantomData;
55

6-
use super::{match_format, match_indices, match_is_continuous, match_total, DataType};
6+
use super::{match_format, DataType, MatMatcher};
77
use crate::boxed_ref::{BoxedRef, BoxedRefMut};
88
use crate::core::{
99
Mat, MatTrait, MatTraitConst, MatTraitConstManual, MatTraitManual, Point, ToInputArray, ToInputOutputArray, ToOutputArray,
@@ -67,25 +67,29 @@ impl<T: DataType> Mat_<T> {
6767
/// See [Mat::at]
6868
#[inline]
6969
pub fn at(&self, i0: i32) -> Result<&T> {
70-
match_total(self, i0).and_then(|_| unsafe { self.at_unchecked(i0) })
70+
self.match_total(i0).and_then(|_| unsafe { self.at_unchecked(i0) })
7171
}
7272

7373
/// See [Mat::at_2d]
7474
#[inline]
7575
pub fn at_2d(&self, row: i32, col: i32) -> Result<&T> {
76-
match_indices(self, &[row, col]).and_then(|_| unsafe { self.at_2d_unchecked(row, col) })
76+
self
77+
.match_indices(&[row, col])
78+
.and_then(|_| unsafe { self.at_2d_unchecked(row, col) })
7779
}
7880

7981
/// See [Mat::at_3d]
8082
#[inline]
8183
pub fn at_3d(&self, i0: i32, i1: i32, i2: i32) -> Result<&T> {
82-
match_indices(self, &[i0, i1, i2]).and_then(|_| unsafe { self.at_3d_unchecked(i0, i1, i2) })
84+
self
85+
.match_indices(&[i0, i1, i2])
86+
.and_then(|_| unsafe { self.at_3d_unchecked(i0, i1, i2) })
8387
}
8488

8589
/// See [Mat::at_nd]
8690
#[inline]
8791
pub fn at_nd(&self, idx: &[i32]) -> Result<&T> {
88-
match_indices(self, idx).and_then(|_| unsafe { self.at_nd_unchecked(idx) })
92+
self.match_indices(idx).and_then(|_| unsafe { self.at_nd_unchecked(idx) })
8993
}
9094

9195
/// See [Mat::at_pt]
@@ -97,34 +101,36 @@ impl<T: DataType> Mat_<T> {
97101
/// See [Mat::at_row]
98102
#[inline]
99103
pub fn at_row(&self, row: i32) -> Result<&[T]> {
100-
match_indices(self, &[row, 0]).and_then(|_| unsafe { self.at_row_unchecked(row) })
104+
self
105+
.match_indices(&[row, 0])
106+
.and_then(|_| unsafe { self.at_row_unchecked(row) })
101107
}
102108

103109
/// See [Mat::at_mut]
104110
#[inline]
105111
pub fn at_mut(&mut self, i0: i32) -> Result<&mut T> {
106-
match_total(self, i0)?;
112+
self.match_total(i0)?;
107113
unsafe { self.at_unchecked_mut(i0) }
108114
}
109115

110116
/// See [Mat::at_2d_mut]
111117
#[inline]
112118
pub fn at_2d_mut(&mut self, row: i32, col: i32) -> Result<&mut T> {
113-
match_indices(self, &[row, col])?;
119+
self.match_indices(&[row, col])?;
114120
unsafe { self.at_2d_unchecked_mut(row, col) }
115121
}
116122

117123
/// See [Mat::at_3d_mut]
118124
#[inline]
119125
pub fn at_3d_mut(&mut self, i0: i32, i1: i32, i2: i32) -> Result<&mut T> {
120-
match_indices(self, &[i0, i1, i2])?;
126+
self.match_indices(&[i0, i1, i2])?;
121127
unsafe { self.at_3d_unchecked_mut(i0, i1, i2) }
122128
}
123129

124130
/// See [Mat::at_nd_mut]
125131
#[inline]
126132
pub fn at_nd_mut(&mut self, idx: &[i32]) -> Result<&mut T> {
127-
match_indices(self, idx)?;
133+
self.match_indices(idx)?;
128134
unsafe { self.at_nd_unchecked_mut(idx) }
129135
}
130136

@@ -137,20 +143,22 @@ impl<T: DataType> Mat_<T> {
137143
/// See [Mat::at_row_mut]
138144
#[inline]
139145
pub fn at_row_mut(&mut self, row: i32) -> Result<&mut [T]> {
140-
match_indices(self, &[row, 0])?;
146+
self.match_indices(&[row, 0])?;
141147
unsafe { self.at_row_unchecked_mut(row) }
142148
}
143149

144150
/// See [Mat::data_typed]
145151
#[inline]
146152
pub fn data_typed(&self) -> Result<&[T]> {
147-
match_is_continuous(self).and_then(|_| unsafe { self.data_typed_unchecked() })
153+
self
154+
.match_is_continuous()
155+
.and_then(|_| unsafe { self.data_typed_unchecked() })
148156
}
149157

150158
/// See [Mat::data_typed_mut]
151159
#[inline]
152160
pub fn data_typed_mut(&mut self) -> Result<&mut [T]> {
153-
match_is_continuous(self)?;
161+
self.match_is_continuous()?;
154162
unsafe { self.data_typed_unchecked_mut() }
155163
}
156164
}

0 commit comments

Comments
 (0)