Refactor swapper code with traits.

Change-Id: Ia27d3a11fea86d2ac430c3455d5247cfc4891e70
diff --git a/src/swapper/c_swap.rs b/src/swapper/c_swap.rs
new file mode 100644
index 0000000..a9d7733
--- /dev/null
+++ b/src/swapper/c_swap.rs
@@ -0,0 +1,43 @@
+use crate::bindings;
+use crate::swapper::Swapper;
+use std::cmp::min;
+use std::mem::size_of;
+
+pub struct CLoopSwapper {}
+impl Swapper for CLoopSwapper {
+    fn swap<T>(a: &mut [T], b: &mut [T]) {
+        unsafe {
+            bindings::swap_loop(
+                a.as_mut_ptr() as *mut i8,
+                b.as_mut_ptr() as *mut i8,
+                (size_of::<T>() * min(a.len(), b.len())) as bindings::size_t,
+            )
+        }
+    }
+}
+
+pub struct CMallocSwapper {}
+impl Swapper for CMallocSwapper {
+    fn swap<T>(a: &mut [T], b: &mut [T]) {
+        unsafe {
+            bindings::swap_malloc(
+                a.as_mut_ptr() as *mut i8,
+                b.as_mut_ptr() as *mut i8,
+                (size_of::<T>() * min(a.len(), b.len())) as bindings::size_t,
+            )
+        }
+    }
+}
+
+pub struct CAllocaSwapper {}
+impl Swapper for CAllocaSwapper {
+    fn swap<T>(a: &mut [T], b: &mut [T]) {
+        unsafe {
+            bindings::swap_alloca(
+                a.as_mut_ptr() as *mut i8,
+                b.as_mut_ptr() as *mut i8,
+                (size_of::<T>() * min(a.len(), b.len())) as bindings::size_t,
+            )
+        }
+    }
+}
diff --git a/src/swapper/mod.rs b/src/swapper/mod.rs
new file mode 100644
index 0000000..47caa9b
--- /dev/null
+++ b/src/swapper/mod.rs
@@ -0,0 +1,7 @@
+mod c_swap;
+mod rust_swap;
+mod swapper;
+
+pub use c_swap::*;
+pub use rust_swap::*;
+pub use swapper::*;
diff --git a/src/swapper/rust_swap.rs b/src/swapper/rust_swap.rs
new file mode 100644
index 0000000..a11f303
--- /dev/null
+++ b/src/swapper/rust_swap.rs
@@ -0,0 +1,20 @@
+use crate::swapper::Swapper;
+
+use core::{mem, ptr};
+use std::cmp::min;
+
+pub struct LoopSwapper {}
+impl Swapper for LoopSwapper {
+    fn swap<T>(a: &mut [T], b: &mut [T]) {
+        for (x, y) in a.iter_mut().zip(b.iter_mut()) {
+            mem::swap(x, y);
+        }
+    }
+}
+
+pub struct PtrSwapper {}
+impl Swapper for PtrSwapper {
+    fn swap<T>(a: &mut [T], b: &mut [T]) {
+        unsafe { ptr::swap_nonoverlapping(a.as_mut_ptr(), b.as_mut_ptr(), min(a.len(), b.len())) }
+    }
+}
diff --git a/src/swapper/swapper.rs b/src/swapper/swapper.rs
new file mode 100644
index 0000000..bf045ee
--- /dev/null
+++ b/src/swapper/swapper.rs
@@ -0,0 +1,3 @@
+pub trait Swapper {
+    fn swap<T>(a: &mut [T], b: &mut [T]);
+}