use crate::mesh_error::MeshSieveError;
use crate::topology::arrow::Polarity;
pub trait SliceDelta<V: Clone>: Sync {
fn apply(&self, src: &[V], dest: &mut [V]) -> Result<(), MeshSieveError>;
}
#[deprecated(note = "Renamed to SliceDelta; Delta will be removed in a future major release")]
pub use SliceDelta as Delta;
impl<V: Clone> SliceDelta<V> for Polarity {
fn apply(&self, src: &[V], dest: &mut [V]) -> Result<(), MeshSieveError> {
let expected = src.len();
let found = dest.len();
if expected != found {
return Err(MeshSieveError::DeltaLengthMismatch { expected, found });
}
match self {
Polarity::Forward => {
dest.clone_from_slice(src);
}
Polarity::Reverse => {
for (d, s) in dest.iter_mut().zip(src.iter().rev()) {
*d = s.clone();
}
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::topology::arrow::Polarity;
#[test]
fn orientation_forward_noop() {
let src = vec![1, 2, 3];
let mut dst = src.clone();
assert!(Polarity::Forward.apply(&src, &mut dst).is_ok());
assert_eq!(dst, src);
}
#[test]
fn orientation_reverse_reverses() {
let src = vec![1, 2, 3, 4];
let mut dst = vec![0; 4];
assert!(Polarity::Reverse.apply(&src, &mut dst).is_ok());
assert_eq!(dst, vec![4, 3, 2, 1]);
}
#[test]
fn orientation_reverse_empty() {
let src: Vec<i32> = vec![];
let mut dst: Vec<i32> = vec![];
assert!(Polarity::Reverse.apply(&src, &mut dst).is_ok());
assert!(dst.is_empty());
}
#[test]
fn orientation_mismatch_errors() {
let src = vec![1, 2, 3];
let mut dst = vec![0; 2];
let err = Polarity::Forward.apply(&src, &mut dst).unwrap_err();
assert_eq!(
err,
crate::mesh_error::MeshSieveError::DeltaLengthMismatch {
expected: 3,
found: 2
}
);
}
}