From 949b2d90a93b871115d56b1ff94d57a117b410d4 Mon Sep 17 00:00:00 2001 From: William Hicklin Date: Fri, 13 Dec 2024 16:19:44 +0000 Subject: [PATCH 1/5] Implemented TyrFrom for Deque from slice. --- CHANGELOG.md | 1 + src/deque.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e823923213..5a287954c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `SortedLinkedListView`, the `!Sized` version of `SortedLinkedList`. - Added implementation of `Borrow` and `BorrowMut` for `String` and `Vec`. - Added `Deque::{swap, swap_unchecked, swap_remove_front, swap_remove_back}`. +- Implemented `TyrFrom` for `Deque` from slice. ### Changed diff --git a/src/deque.rs b/src/deque.rs index 4c0bec81dc..2a94b43249 100644 --- a/src/deque.rs +++ b/src/deque.rs @@ -36,7 +36,7 @@ use core::borrow::{Borrow, BorrowMut}; use core::fmt; use core::iter::FusedIterator; -use core::mem::MaybeUninit; +use core::mem::{ManuallyDrop, MaybeUninit}; use core::{ptr, slice}; use crate::storage::{OwnedStorage, Storage, ViewStorage}; @@ -950,6 +950,50 @@ where } } +impl TryFrom<[T; NS]> for Deque { + /// Converts a `[T; NS]` into a `Deque`. + /// + /// ``` + /// use heapless::Deque; + /// + /// let deq1 = Deque::::try_from([1, 2, 3, 4]).unwrap(); + /// let mut deq2 = Deque::::new(); + /// deq2.push_back(1).unwrap(); + /// deq2.push_back(2).unwrap(); + /// deq2.push_back(3).unwrap(); + /// deq2.push_back(4).unwrap(); + /// + /// // todo change to `assert_eq!(deq1, deq2);` when PR #521 is merged. + /// assert_eq!(deq1.len(), deq2.len()); + /// for (i, e1) in deq1.iter().enumerate() { + /// assert_eq!(Some(e1), deq2.get(i)); + /// } + /// ``` + type Error = (); + + fn try_from(value: [T; NS]) -> Result { + if NS > ND { + return Err(()); + } + + let mut deq = Self::default(); + let value = ManuallyDrop::new(value); + + if size_of::() != 0 { + // SAFETY: We already ensured that value fits in deq. + unsafe { + ptr::copy_nonoverlapping(value.as_ptr(), deq.buffer.as_mut_ptr() as *mut T, NS); + } + } + + deq.front = 0; + deq.back = NS; + deq.full = NS == ND; + + Ok(deq) + } +} + #[cfg(test)] mod tests { use static_assertions::assert_not_impl_any; From 9cd3bc785914c766f96a37e9e4ceaaad6feaf3c4 Mon Sep 17 00:00:00 2001 From: William Hicklin Date: Mon, 16 Dec 2024 14:27:21 +0000 Subject: [PATCH 2/5] Added tests for the try_from slice method. --- src/deque.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/deque.rs b/src/deque.rs index 2a94b43249..f1cbec7cae 100644 --- a/src/deque.rs +++ b/src/deque.rs @@ -1484,4 +1484,23 @@ mod tests { q.pop_front().unwrap(); q.swap(0, 2); } + + #[test] + fn tyr_from_slice() { + + assert!(Deque::::try_from([1, 2, 3, 4]).is_err()); + + let deq1 = Deque::::try_from([1, 2, 3, 4]).unwrap(); + let mut deq2 = Deque::::new(); + deq2.push_back(1).unwrap(); + deq2.push_back(2).unwrap(); + deq2.push_back(3).unwrap(); + deq2.push_back(4).unwrap(); + + // todo change to `assert_eq!(deq1, deq2);` when PR #521 is merged. + assert_eq!(deq1.len(), deq2.len()); + for (i, e1) in deq1.iter().enumerate() { + assert_eq!(Some(e1), deq2.get(i)); + } + } } From 8e19f2cc7a8ed1573d5f11f8112ecdd78b0fdca9 Mon Sep 17 00:00:00 2001 From: William Hicklin Date: Mon, 16 Dec 2024 14:38:40 +0000 Subject: [PATCH 3/5] Fixed the style. --- src/deque.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/deque.rs b/src/deque.rs index f1cbec7cae..8abcf3c0d0 100644 --- a/src/deque.rs +++ b/src/deque.rs @@ -966,7 +966,7 @@ impl TryFrom<[T; NS]> for Deque { /// // todo change to `assert_eq!(deq1, deq2);` when PR #521 is merged. /// assert_eq!(deq1.len(), deq2.len()); /// for (i, e1) in deq1.iter().enumerate() { - /// assert_eq!(Some(e1), deq2.get(i)); + /// assert_eq!(Some(e1), deq2.get(i)); /// } /// ``` type Error = (); @@ -1487,7 +1487,6 @@ mod tests { #[test] fn tyr_from_slice() { - assert!(Deque::::try_from([1, 2, 3, 4]).is_err()); let deq1 = Deque::::try_from([1, 2, 3, 4]).unwrap(); @@ -1500,7 +1499,7 @@ mod tests { // todo change to `assert_eq!(deq1, deq2);` when PR #521 is merged. assert_eq!(deq1.len(), deq2.len()); for (i, e1) in deq1.iter().enumerate() { - assert_eq!(Some(e1), deq2.get(i)); + assert_eq!(Some(e1), deq2.get(i)); } } } From 306528a33380359f3d83c3afebbea7f8f4a95ba9 Mon Sep 17 00:00:00 2001 From: William Hicklin Date: Mon, 6 Jan 2025 15:42:45 +0000 Subject: [PATCH 4/5] Fixed typo. --- src/deque.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deque.rs b/src/deque.rs index 8abcf3c0d0..06d2e4b0b5 100644 --- a/src/deque.rs +++ b/src/deque.rs @@ -1486,7 +1486,7 @@ mod tests { } #[test] - fn tyr_from_slice() { + fn tyr_from_array() { assert!(Deque::::try_from([1, 2, 3, 4]).is_err()); let deq1 = Deque::::try_from([1, 2, 3, 4]).unwrap(); From aa6f7a21b6f3efd0d306ca95fd725bd1cc7aec62 Mon Sep 17 00:00:00 2001 From: William Date: Tue, 14 Jan 2025 11:51:24 +0000 Subject: [PATCH 5/5] Apply typo suggestions from code review Co-authored-by: Alex Martens --- CHANGELOG.md | 2 +- src/deque.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a287954c8..cf1bf7111e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `SortedLinkedListView`, the `!Sized` version of `SortedLinkedList`. - Added implementation of `Borrow` and `BorrowMut` for `String` and `Vec`. - Added `Deque::{swap, swap_unchecked, swap_remove_front, swap_remove_back}`. -- Implemented `TyrFrom` for `Deque` from slice. +- Implemented `TryFrom` for `Deque` from slice. ### Changed diff --git a/src/deque.rs b/src/deque.rs index 06d2e4b0b5..bdcaf4fc25 100644 --- a/src/deque.rs +++ b/src/deque.rs @@ -1486,7 +1486,7 @@ mod tests { } #[test] - fn tyr_from_array() { + fn try_from_array() { assert!(Deque::::try_from([1, 2, 3, 4]).is_err()); let deq1 = Deque::::try_from([1, 2, 3, 4]).unwrap();