diff --git a/src/lib.rs b/src/lib.rs
index d9b2afab09311b409c322df24cacb5a1f45b7c62..1f46b823b32bc177b33f475e762678ff12a829ec 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -135,42 +135,45 @@ where
         &mut self,
         new_buf: Option<&'a mut [u8; MAX_PACKET_LEN]>,
     ) -> Result<Option<RxPacket<MAX_PACKET_LEN>>, Spi::Error> {
-        let (set_idle, ret) = match &mut self.state {
+        let mut old_state = InternalState::Idle;
+        core::mem::swap(&mut old_state, &mut self.state);
+
+        let ret = match old_state {
             InternalState::Rx {
                 data,
                 received,
                 i,
                 rssi,
-            } if *received => {
-                let ret_rssi = match *rssi {
+            } if received => {
+                let ret_rssi = match rssi {
                     Some(x) => x,
                     None => self.radio.get_rssi()?,
                 };
 
-                let ret = if self.rx_forever {
+                if self.rx_forever {
                     let new_buf = new_buf.expect("rx_forever=true and no replacement buffer given");
-
                     self.radio.clear_ph_and_modem_interrupts()?;
 
-                    core::mem::swap(new_buf, data);
-                    *i = 0;
-                    *received = false;
-                    *rssi = None;
+                    self.state = InternalState::Rx {
+                        data: new_buf,
+                        i: 0,
+                        received: false,
+                        rssi: None,
+                    };
+                }
 
-                    (false, Some(RxPacket::new(new_buf, *i, ret_rssi)))
-                } else {
-                    (true, Some(RxPacket::new(data, *i, ret_rssi)))
-                };
+                // state is implicitly Idle now if rx_forever=false, based on the mem::swap we did above
 
-                ret
+                Some(RxPacket::new(data, i, ret_rssi))
             }
 
-            _ => (false, None),
-        };
+            _ => {
+                // swap our states back
+                core::mem::swap(&mut old_state, &mut self.state);
 
-        if set_idle {
-            self.state = InternalState::Idle;
-        }
+                None
+            }
+        };
 
         Ok(ret)
     }
diff --git a/src/rx.rs b/src/rx.rs
index e7f99d6837fc89b2073b2573ef465fc3622c3583..644281d0d513475631b85f965320d05390e99b60 100644
--- a/src/rx.rs
+++ b/src/rx.rs
@@ -18,7 +18,7 @@ impl<'a, const N: usize> RxPacket<'a, N> {
         self.rssi
     }
 
-    fn into_buf(self) -> &'a mut [u8; N] {
+    pub fn into_buf(self) -> &'a mut [u8; N] {
         self.data
     }
 }